You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Andriy Redko <dr...@gmail.com> on 2022/06/13 23:08:13 UTC

Re: JAXRS server endpoint not gracefully shutdown

Hi Jean,

Indeed, the jaxrs:server does not expect address to be omitted, you could use
the "/" (and I believe an empty string would also make it):

<jaxrs:server id="restServer" basePackages="xxx" address="/">
...
</jaxrs:server>


Thank you.
Hope it helps.

Best Regards,
    Andriy Redko
 

JPU> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean declarations

JPU> like:

JPU>      <jaxrs:server id="restServer" basePackages="xxx">

JPU>            <jaxrs:serviceBeans>

JPU>                 <ref bean="TestApi" />

JPU>            </jaxrs:serviceBeans>

JPU>            <jaxrs:providers>

JPU>                 <…/>

JPU>            </jaxrs:providers>

JPU>            <jaxrs:features>

JPU>                 <… />

JPU>            </jaxrs:features>

JPU>            <jaxrs:inInterceptors>

JPU>                 <… />

JPU>            </jaxrs:inInterceptors>

JPU>            <jaxrs:outInterceptors>*

JPU>                 <**…**/>*

JPU>            </jaxrs:outInterceptors>*

JPU>      </jaxrs:server>





JPU> Here my “TestApi” bean interface is declared like:



JPU>       @Path("accounts")

JPU>        @Consumes(MediaType.*APPLICATION_JSON*)

JPU>        @Produces(MediaType.*APPLICATION_JSON*)

JPU>        public interface TestApi {

JPU>          …

JPU>        }



JPU> And CXF is triggered via a servlet configuration like:

JPU>      <servlet>

JPU>              <display-name>CXF Servlet</display-name>

JPU>              <servlet-name>CXFServlet</servlet-name>


JPU> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>

JPU>        </servlet>

JPU>        <servlet-mapping>

JPU>              <servlet-name>CXFServlet</servlet-name>

JPU>              <url-pattern>/services/*</url-pattern>

JPU>        </servlet-mapping>





JPU> Because I’ve got the @Path declaration on the interface type I’ve omitted

JPU> the address=”accounts” attribute on the jaxrs:server declaration since
JPU> otherwise

JPU> I noticed that the server would be listening to /basepath/services/
JPU> accounts/accounts/…).



JPU> Now this configuration works perfectly, only when shutting down the
JPU> application server cxf calls

JPU>         ServerImpl#destroy()



JPU> which delegates (via Obeservable) to AbstractHTTPDestination#deactivate()
JPU> which calls

JPU> registry.removeDestination(path).

JPU> This path is null (no ‘address’ specified on jaxrs:server declaration) and
JPU> results in a NPE on the registry Map.

JPU> This causes an unclean shutdown of my server.



JPU> Is this an error in cxf or is my jaxrs:server configured incorrectly?

JPU> How does the ‘address’ attribute on the jaxrs:server declaration correctly
JPU> interact with the @Path parameter on the API interface?


RE: Handle Bearer authorization

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
Using javax.ws.rs.core.SecurityContext works.

Best Regards,

J.P.

-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: vrijdag 2 juni 2023 23:11
To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev List
<de...@cxf.apache.org>
Subject: Re: Handle Bearer authorization

Hi Jean,

Apologies since I am rarely touching this part of the project, and do have
some knowledge gaps there. Anyway, the flow I was sure should work actually
does not [1] apparently. There are 2 security contexts actually:

 - javax.ws.rs.core.SecurityContext (or jakarta.ws.rs.core.SecurityContext)
 - org.apache.cxf.security.SecurityContext

I was thinking about the latter but due to [1], the injection does not work.
Could you try to use javax.ws.rs.core.SecurityContext instead please to see
what is being injected to you?

Thank you.

[1] https://issues.apache.org/jira/browse/CXF-5803

Best Regards,
    Andriy Redko

> I did a test where I:
> - created my own SecurityContext implementation
> - in my authentication filter I construct an instance 'sc' of this
> SecurityContext and put in the message using:
> JAXRSUtils.getCurrentMessage().put(SecurityContext.class, sc);

> I tried two ways to obtain this SecurityContext my service methods:
>  1. using annotations:
>         Interface:                 Response
> getOnderneming(@HeaderParam("X-KMO-OPERATION-ID") UUID
> operationId,@PathParam("kboNr")  String kboNr,@Context SecurityContext
> sc);
>         Implementation:    Response getOnderneming(UUID operationId,
> String kboNr,
> SecurityContext sc){...}  2.without annotations:
>         Interface:                 Response
> getOnderneming(@HeaderParam("X-KMO-OPERATION-ID") UUID
> operationId,@PathParam("kboNr")  String kboNr);
>         Implementation:    Response getOnderneming(UUID operationId,
> String kboNr,
> SecurityContext sc){
>                                 SecurityContext sc =
> JAXRSUtils.getCurrentMessage().get(SecurityContext.class);
>                                 ...
>                              }Using the annotations (1. above) way
> doesn't work the SecurityContext object 'sc' is null on entering the
> getOnderneming() method.
> Without annotations  (2. Above) I do get a valid SecurityContext
> object 'sc'.

> Isn't the 'annotations'-way supposed to work this way?

> Regards,

> J.P. Urkens

> -----Original Message-----
> From: Jean Pierre URKENS <je...@devoteam.com>
> Sent: vrijdag 2 juni 2023 10:18
> To: 'Andriy Redko' <dr...@gmail.com>
> Subject: RE: Handle Bearer authorization

> Hi Andriy,

> As far as I understand the filters JwtAuthenticationFilter and
> AbstractJwtAuthenticationFilter the assumption is that a request is
> received with an 'Authentication' header that contains a signed JWT
> token. The filter provides in methods to:
> -  validate the signed JWT token
> - to create a SecurityContext (JwtTokenSecurityContext) from it.

> This isn't the situation I am dealing with. I am receiving a request
> with an 'Authorization' header containing 'Bearer <access_token>'.
> I've no knowledge about the nature of this access_token, nor do I need
> to since validating this access token is done by sending a request to
> an 'OAuth/OIDC introspection endpoint' passing on this access_token.
> The introspection endpoint replies with a scope object (JWT claims
> object) if the token is valid.

> Now I can deal with this situation and create my own SecurityContext
> (extended from ClaimsSecurityContext). What I don't understand is how
> I get this SecurityContext available in my service method.

> I see that the AbstractJwtAuthenticationFilter (line 56) puts the
> constructed SecurityContext in the Message:
>         if (securityContext != null) {
>
> JAXRSUtils.getCurrentMessage().put(SecurityContext.class,
> securityContext);
>         }

> Can I simply retrieve this in my service method by calling:
>         SecurityContext sc =
> JAXRSUtils.getCurrentMessage().get(SecurityContext.class);

> So no need to add  @Context annotations to service methods like e.g.:

> Interface:                 Response
> getOnderneming(@HeaderParam("X-KMO-OPERATION-ID") UUID
> operationId,@PathParam("kboNr")  String kboNr,@Context SecurityContext
> ctx);
> Implementation:    Response getOnderneming(UUID operationId, String kboNr,
> SecurityContext sc){...}

> Regards,

> J.P.
> -----Original Message-----
> From: Andriy Redko <dr...@gmail.com>
> Sent: vrijdag 2 juni 2023 0:29
> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev List
> <de...@cxf.apache.org>
> Subject: Re: Handle Bearer authorization

> Hi Jean,

> You should be able to get access to the Bearer and claims using
> JwtAuthenticationFilter + @Context SecurityContext The expected type
> of the security context should be ClaimsSecurityContext, with
> collection of claims being available.
> If the JwtAuthenticationFilter does not work for you (for some
> reasons), you could subclass AbstractJwtAuthenticationFilter.
> Hope it helps, thank you.

> Best Regards,
>     Andriy Redko

>> Hi Andriy,

>> I am lost in JAXRS JOSE security to figure out how to handle bearer
>> authorization. So what I currently did is:
>>   1. I created an ContainerRequestFilter to retrieve the Bearer
>> access token from the request and query the introspection endpoint
>> which returns the JWTClaims
>>   2.I added this filter in the Ininterceptor chain

>> This works, i.e. the filter is hit and it queries the introspection
>> endpoint which returns JWTClaims. The problem is that I need these
>> claims available in my service methods and I don't know how to pass
>> them from the ContainerRequestFilter to my service method. Thus far I
>> have been looking to save the JWTClaims as a property in the
>> ContainerRequestContext  which is available in my filter and inject
>> this context in my service methods with the @Context annotation. As
>> documented in
>> https://cxf.apache.org/docs/jax-rs-basics.html#JAXRSBasics-Contextann
>> o tations a number of context types can be injected with the @Context
>> annotation but I am not sure I can inject a ContainerRequestContext.

>> So I annotated my interface method as:
>>                 Response getOnderneming(
>>                         @HeaderParam("X-KMO-OPERATION-ID")
>> @NotNull(message="ERROR_2121") UUID operationId,
>>                         @PathParam("kboNr")
>> @NotNull(message="ERROR_2119") @Pattern(regexp =
>> "^\\d{10}$",message="ERROR_2216") String kboNr,
>>                         @Context ContainerRequestContext ctx);  And
>> my implementation method as:
>>                 Response getOnderneming(UUID operationId, String
>> kboNr, ContainerRequestContext ctx)

>> Unfortunately the ctx=null when the implementation method is called.

>> So my questions are:
>>  1.Is there a way to get the ContainerRequestContext available in my
>> service methods?
>>  2.If the answer to '1.' Is no how do I pass information constructed
>> in request filters to my service methods?
>>  3.Generally, is this the correct way to handle bearer authorization?
>> There is a lot of stuff in cxf-rt-rs-security-jose-(jaxrs) but I
>> can't really figure out how to use it. Anyway it is not sufficient
>> for me to have a filter that validates the bearer token. I need the
>> associated 'scope'
>> information in my service method as it contains information I'll need
>> in my business methods.

>> Regards,

>> J.P. Urkens

>> -----Original Message-----
>> From: Jean Pierre URKENS <je...@devoteam.com>
>> Sent: donderdag 25 mei 2023 9:48
>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'
>> <de...@cxf.apache.org>
>> Subject: RE: How to setup multiple JAXRS server endpoints

>> Hi Andriy,

>> The issue seems to be that the Reader is scanning the implementation
>> classes while the @SwaggerDefinition (and all other swagger
>> annotations) were on the interface class.

>> So
>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-
>> j axrs/src/main/java/io/swagger/jaxrs/Reader.java#L171,
>> scanning for @SwaggerDefinition, doesn't get triggered.
>> However via
>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-
>> j axrs/src/main/java/io/swagger/jaxrs/Reader.java#L176,
>> through reflection, the remaining swagger annotation information is
>> retrieved, just not the @SwaggerDefinition.

>> So, I moved the @SwaggerDefintion to the implementation class and now
>> it is ok.

>> Thanks for the advice,

>> J.P.

>> -----Original Message-----
>> From: Andriy Redko <dr...@gmail.com>
>> Sent: donderdag 25 mei 2023 2:27
>> To: Jean Pierre URKENS <je...@devoteam.com>;
>> dev@cxf.apache.org
>> Subject: Re: How to setup multiple JAXRS server endpoints

>> Hi Jean,

>> You may run into Swagger JAX-RS scanner limitations, as far as I can
>> tell - it checks class annotations for SwaggerDefinition, does not
>> traverse the hierarchy [1].

>> [1]
>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-
>> j
>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194

>> Best Regards,
>>     Andriy Redko

>>>  RE: How to setup multiple JAXRS server endpoints

>>> Still one question );

>>> The generated swagger file doesn’t take into account the
>>> @SwaggerDefintion on my interface classes?

>>> As a test I looked at
>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma
>>> in/release/samples/jax_rs/description_swagger2_web**
>>> and** modified** sample2*
>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma
>>> in/release/samples/jax_rs/description_swagger2_web
>>> and modified sample2> as follows:

>>>    @Path("/sample2")

>>>       @Api(value = "/sample2",authorizations=
>>>       {@Authorization(value="bearer")},description = "Sample2

>> (modified) JAX-RS
>>>       service with Swagger documentation")

>>>       @SwaggerDefinition(

>>>               info = @Info(

>>>                       description = "Sample2 server",

>>>                       version="1.0",

>>>                       title = "Test2",

>>>                       contact = @Contact(name = "J.P. Urkens",email = "
>>>       *jean-pierre.urkens@devoteam.com*

>> <je...@devoteam.com>
>>>       ")),

>>>               securityDefinition =
>>>       @SecurityDefinition(apiKeyAuthDefinitions=

>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="A
>> u
>> thorization",description="Use*
>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer
>>>       &lt;accessToken&gt;'")})

>>>       )

>>>       public class Sample2 {...}

>>> This correctly generates the ‘securityDefintions’ in the swagger file.

>>> If include the same @SwaggerDefinition and the authorizations on the
>>> @Api annotation as above in my interface classes then the generated
>>> swagger file doesn’t contain the ‘securityDefintions’ ?

>>> Any idea what I might be missing?

>>> Regards,

>>> J.P.

>>> -----Original Message-----
>>> From: Jean Pierre URKENS <je...@devoteam.com>
>>> Sent: dinsdag 23 mei 2023 12:52
>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <

>>> Subject: RE: How to setup multiple JAXRS server endpoints

>>> Hi Andriy,

>>> I added the parameter usePathBasedConfig=true to the Swagger2Feature
>>> bean declarations but still it does generate an empty swagger.yaml
>>> for interfaces KmopResources and KmopDienstverlener although I
>>> noticed that for these interfaces the
>>> @Path() annotation was commented out (as I included it in the server
>>> declaration). After providing an empty @Path("") declaration on

>> the API interface classes everything worked.

>>> Thanks for the support.

>>> -----Original Message-----

>>> From: Andriy Redko <dr...@gmail.com>

>>> Sent: dinsdag 23 mei 2023 3:42

>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>>> dev@cxf.apache.org

>>> Subject: Re: How to setup multiple JAXRS server endpoints

>>> Hi Jean,

>>> The main problem to configure Swagger property in your particular
>>> case is that the server address is not "known" or "introspectable"
>>> for

>> Swagger.
>>> Intuitively, it has to be set manually using basePath to the,
>>> essentially, the server address

>>> part:

>>>  - /op/services/accounts

>>>  - /op/services/resources

>>>  - /op/services/dienstverlener

>>> You could read more about other Swagger properties you have asked here:
>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte
>>> gration-and-Configuration#configuration-properties

>>> You definitely need to set usePathBasedConfig to "true" otherwise
>>> you will see the same Swagger specs for all servers. We have a
>>> sample here which uses 2 jaxrs:server

>>> instances:
>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai
>>> n/release/samples/jax_rs/description_swagger2_web

>>> Regarding SwaggerUI, I think the value for each of those should be
>>> set to,
>>> respectively:

>>>  - /op/services/accounts/swagger.yaml

>>>  - /op/services/resources/swagger.yaml

>>>  - /op/services/dienstverlener/swagger.yaml

>>> I believe this is matching your settings already, except the
>>> usePathBasedConfig part. The example referred above could be
>>> helpful, my apologies if I missed something, there are quite a lot
>>> of questions :-) The fact that the generated Swagger specification
>>> is empty is unexpected - it should not happen when JAX-RS resources
>>> are

>> properly configured.

>>> Thank you.

>>> Best Regards,

>>>     Andriy Redko

>>>>  RE: How to setup multiple JAXRS server endpoints

>>>> Hi Andriy,

>>>> I am not quite understanding how to correctly configure the

>>> Swagger2Feature.

>>>> Referring to the attached cxf-endpoints configuration I (as a
>>>> test)

>>>> created

>>>> 3 JAXRS server instances:

>>>> 1.      A* KmopApiServer* server for the*

>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving

>>>> requests for URI path:

>>>>        * <protocol>**//<host:<port>/op/services/accounts*

>>>>    ‘op’  = root path of the web application

>>>>             ‘services’ = servlet path of the CXF-servlet

>>>>       The address of the server is set to ‘/accounts’ and the
>>>> @Path(…)

>>>>       annotation on the interface class was cleared.

>>>> 2.      A* Kmop**Resources**ApiServer* server for the*

>> be.dvtm.aeo.op.*

>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving

>>>> requests for URI path:

>>>>        * <protocol>**//<host:<port>/op/services/**resources*

>>>> The address of the server is set to ‘/resources’ and the @Path(…)

>>>> annotation on the interface class was cleared.

>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*

>>> be.dvtm.aeo.op.*

>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving

>>>> requests for URI path:

>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*

>>>> The address of the server is set to ‘/dienstverlener’ and the

>>>> @Path(…) annotation on the interface class was cleared.

>>>> For each of these server instances I’ve set the Swagger2Feature

>>>> with configuration as indicated in the attached cxf-endpoints.xml.

>>>> With regard to the configurations for the Swagger2Feature I’ve the

>>>> following questions:

>>>> a)      Referring to

>> *https://cxf.apache.org/docs/swagger2feature.html*

>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you

>>>> clarify on the following configuration parameters:

>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘

>>>> /op/services’) or to the JAX-RS server instance (e.g.

>>>> ‘/op/services/accounts’) or still something else? Is it used to

>>>> resolve service classes or is it just for documentation in the
>>>> swagger

>>> file?

>>>> *ii.    ** resourcePackage* – the description mentions ‘package names’

>>>> while the default mentions ‘service classes’? Service 2 and 3 above

>>>> are within the same package (generated from the same yaml

>>>> specification that included both interfaces).

>>>> *iii.   ** ig**noreRoutes* – is this taken into account when

>>>> scanAllResources=false?

>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter

>> value

>>>> (cf. question ‘a’)?

>>>> b)      What would be the correct URL to generate a swagger.yaml file

>>> for

>>>> each of the above interfaces? Initially I called:

>>>> *i.     **

>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*

>>>> *ii.    **

>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*

>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*

>>>> *lener/swagger.yaml*

>>>>    All three requests delivered the same yaml specification, namely

>>> the one

>>>>       for interface* KmopApiServer*?

>>>> c)      I tried to debug the processing of the requests under ‘b)’ and

>>> this

>>>> is done by the class JAXRSInterceptor#processRequest where the

>>>> MessageImpl object for request “ii.” looks like the one attached.

>>>> It finds 3 resource

>>>> classes:

>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl

>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource

>>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService

>>>> è       It matches the request to resource*

>>> Swagger2ApiListingResource* with

>>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*

>>>> process(…)* method.

>>>> è       Here it seems to go wrong. It generates a

>> SwaggerContextService

>>>> having basePath=/op/services/resources/,swaggerConfig=null,

>>>> usePathBasedConfig=null and then calls

>>>> SwaggerContextService.getSwagger()

>>>> which returns the Swagger definition for interface KmopApiServer?

>>>> It looks like it caches generated swagger definitions based on a

>>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the

>>>> same for all 3 interfaces as usePathBasedConfig=null

>>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is

>>>> derived from the ServletConfig parameter

>>>> ‘swagger.use.path.based.config’.* So should this be set on the

>>>> declaration of the CXFServlet** in web.xml?*

>>>> è       Actually the SwaggerConfig, the JaxrsScanner and the generated

>>> Swagger

>>>> are cached using keys like

>>>> ‘swagger.config.id.[default|baseUriPath]’, ‘

>>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’

>>> is only done when usePathBasedconfig=true.

>>>> è       If I patch this to true then configIdKey=’

>>>> swagger.config.id./op/services/resources/’ and no swagger entry is

>>>> cached for this key so it will generate a new one. Again by

>>>> patching

>>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru
>>>> e

>>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”

>>>> è       Again Scanners are cached and if usePathBasedConfig=null it

>>> will use

>>>> the one cached under  ‘swagger.scanner.id.default’ and this again

>>>> returns the swagger definition for the KmopApiService interface.

>>>> è       So patching usePathBasedConfig=true will return a new one

>>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner

>>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘

>>>> which is correct. It will generate a new (but empty) Swagger object.

>>>> è       Next Swagger2ApiListingResource will call the

>>>> customizer.customize(s), which still isn’t putting anything new in

>>>> the Swagger object. Should it or should the next step do this?

>>>> è       Next BaseApiListingResource#getListing(…) is called which on

>>> its

>>>> turn calls getListingYamlResponse(..)

>>>> è       The final result is a swagger.yaml document with following

>>> content:

>>>>    swagger: "2.0"

>>>>       info:

>>>>         license:

>>>>           name: "Apache 2.0 License"

>>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html

>>>>       basePath: "/op/services/resources"

>>>>        So basically an empty swagger file.

>>>> d)      The usePathBasedConfig is derived from the ServletConfig

>>> parameter ‘

>>>> swagger.use.path.based.config’. Without this parameter set to true

>>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger

>>>> object.* So should this be set on the declaration of the

>>>> CXFServlet** in web.xml?*

>>>> The majority in this processing happens in the library

>>>> swagger-jaxrs-v1.6.10 which is included as a dependency on

>>> cxf-rt-rs-service-description-swagger.

>>>> Even if I patch usePathBasedConfig=true about everywhere where I

>>>> met this it still doesn’t generate a correct swagger.yaml. Am I

>>>> still missing some configuration parameter?

>>>> Any suggestions on how to resolve this would be welcome.

>>>> Regards,

>>>> J.P. Urkens










>>>> <<...>> <<...>>

>>>> -----Original Message-----

>>>> From: Andriy Redko <dr...@gmail.com>

>>>> Sent: maandag 8 mei 2023 23:15

>>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev

>>>> List <


>>>> Subject: Re: How to setup multiple JAXRS server endpoints

>>>> Hi Jean,

>>>> Indeed the way you would like to do that is somewhat tricky.

>>>>> So I tried to keep the @Path declaration on the interface classes
>>>>> but

>>>> changed them to @Path(“”). That does seems to work except the

>>>> swagger stuff no longer correctly works.

>>>> This is one of the possible options but OpenAPI/Swagger gets

>>>> confused for a

>>>> reason: the path is now implicit (not in the spec).

>>>> So how about this option:

>>>>  - use only one JAX-RS server (address "/")

>>>>  - host both resources but use @Path("accounts") and

>>>> @Path("resources") on them respectively


>>>> I see that for @Path("accounts") you need to apply the

>>>> "kmopApiAuthorizationFilter", that could be done using

>>>> DynamicFeature [1], [2]. If this is not the option and you would

>>>> prefer to use 2 separate JAX-RS servers, you may need to provide

>>>> your own instance of Swagger2Customizer [3], [4] which allows to

>>>> transform the OpenAPI/Swagger on the fly. Please let me know if
>>>> that

>>> would it work for you, thank you.

>>>> [1]

>>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic
>>>> F

>>>> eature.html

>>>> [2]

>>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born
>>>> -

>>>> equal.html

>>>> [3]

>>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger
>>>> /

>>>> Swagger2Customizer.html

>>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has

>>>> customizer

>>>> property)


>>>> Best Regards,

>>>>     Andriy Redko

>>>>> Hi Andriy,

>>>>> I am again getting into trouble with server endpoint declarations.

>>>>> Now

>>>> because I am adding additional JAX-RS endpoints.

>>>>> The issue is with:

>>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration in

>>>> combination with

>>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the
>>>>> web.xml

>>>> in combination with

>>>>> 3.      The @Path declaration in the interface class in combination
>>>>> with

>>>>> 4.      The @Path declaration on the interface method in combination
>>>>> with

>>>>> So what I had is that my web application deployed under baseUlr 'op'

>>>>> had

>>>> one JAXRS server endpoint with declarations like:

>>>>> 1.      <jaxrs:server id="restServer"

>>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">

>>>>> 2.      <url-pattern>/services/*</url-pattern>

>>>>> 3.      @Path("accounts") on the public interface class

>>>>> 4.      @Path("/{authorisationId}/customerFund") on the customerFund

>>>> interface method

>>>>> A valid API call would thus be e.g.:

>>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/c
>>>>> u
>>>>> s
>>>>> t

>>>>> o

>>>>> merFund

>>>>> And this works correctly.

>>>>> We're now introducing additional JAX-RS service endpoints and now
>>>>> I

>>>>> am

>>>> running into problems. This second endpoint was declared with:

>>>>> 1.      <jaxrs:server id="resourceServer"

>>>> basePackages="be.dvtm.aeo.op.resources" address="/">

>>>>> 2.      <url-pattern>/services/*</url-pattern>

>>>>> 3.      @Path("resources") on the public interface class

>>>>> 4.      @Path("/NACE") on the NACE interface method

>>>>> So here a valid API call woud be:

>>>> https://<hostname>:<port>/op/services/resources/NACE.

>>>>> The problem is that I can not declare two <jaxrs:server> entries
>>>>> with

>>>>> the

>>>> same ‘address’ as it throws the exception:

>>>>> Caused by:
>>>>> org.apache.cxf.service.factory.ServiceConstructionException:

>>>> There is an endpoint already running on /.

>>>>>  So I tried changing the addresses to:

>>>>> ·       address=”accounts” for the restServer

>>>>> ·       address=”resources” for the resourceServer

>>>>> But to keep the API-call URLs the same I removed the @Path

>>>>> declaration on

>>>> the interface classes. By doing so the <jaxrs:server> bean

>>>> declarations no longer loads successfully.

>>>>> So I tried to keep the @Path declaration on the interface classes
>>>>> but

>>>> changed them to @Path(“”). That does seems to work except the

>>>> swagger stuff no longer correctly works.

>>>>> So what is the decent way to setup multiple JAX-RS server
>>>>> endpoints

>>>>> where

>>>> each server has its own configuration regarding supported features:

>>>>> ·       own validation

>>>>> ·       own object and exception mappings

>>>>> ·       own swagger file generation

>>>>> ·       own logging (in separate file if possible)

>>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in

>>>>> cooperation

>>>> with swager-ui v4.5.0.

>>>>> Below the declarations of my endpoints <<...>> Thanks for any advice.

>>>>> Regards,

>>>>> J.P. Urkens

>>>>> -----Original Message-----

>>>>> From: Andriy Redko <dr...@gmail.com>

>>>>> Sent: zaterdag 18 juni 2022 1:12

>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>>>> issues@cxf.apache.org; dev@cxf.apache.org

>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi
>>>>> Jean,

>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'

>>>>> Correct, so in the relative form like address="/<something>", the

>>>>> JAX-RS

>>>> endpoint path would be:

>>>>>     <baseUrl>/<servlet path

>>>>>> /<address>/[@ApplicationPath]/[@Path]

>>>>> The @ApplicationPath is optional in this case.

>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'

>>>>> The JAX-WS is very different from JAX-RS, essentially the action

>>>>> comes

>>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/

>>>> (@Path / @ApplicationPath are not relevant there).

>>>>>> Question: Because now address="/" is set for the jaxrs:server
>>>>>> will

>>>>>> it

>>>>>> also inspect requests targeted for the jaxws service as those

>>>>>> requests have start with the same path '/<basePath>/services/...

>>>>> This is a good question, I have not done it myself but I think it

>>>>> should

>>>> work:

>>>>> the servlet dispatches according to registered services, in this

>>>>> regard

>>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?

>>> Thank you.

>>>>> Best Regards,

>>>>>     Andriy Redko

>>>>>> Hi Andriy,

>>>>>> Using address="/" seems to work but still I don't understand how
>>>>>> the

>>>>>> following work together:

>>>>>>  - path specification in servlet mapping for the CXF servlet

>>>>>> (org.apache.cxf.transport.servlet.CXFServlet)

>>>>>>  - the 'address' attribute on the jaxrs:server bean declaration

>>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the

>>>>>> service API description Say I've two services with (relateive to
>>>>>> the

>>>>>> host) url's:

>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'

>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'

>>>>>> How do I configure above 3 aspects? Currently I have (working):

>>>>>> 1.for the jaxrs:server endpoint:

>>>>>>         - servlet path mapping: '/services/*'

>>>>>>                - jaxrs-server address attribute: address="/"

>>>>>>                - @Path annotation: @Path("service1") 2.For the
>>>>>> jaxws

>>>>>> service endpoint:

>>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS

>>>>>> requests are handleb by the same CXF servle)

>>>>>>                - jaxws:endpoint server address attribute:

>>>>>> address="/service2"

>>>>>>                - @WebService(name="service2") A correct request
>>>>>> for

>>>>>> '1' would be '/basePath>/services/service1/<ID>'.

>>>>>> A correct request for '2' would be '/basePath>/services/service2'.

>>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect
>>>>>> to:

>>>>>>         - the server address attribute

>>>>>>         - The API annotation (@Path or @Webservice) The JAXWS
>>>>>> server

>>>>>> address attribute doesn't seem to interfere with the @Webservice

>>>>>> annotation. While the jaxrs server address attribute does seem to

>>>>>> interfere with the @Path annotation. I would have expected the
>>>>>> jaxrs

>>>>>> server aspects to be configured as:

>>>>>>         - servlet path mapping: '/services/*'

>>>>>>                - jaxrs-server address attribute: address="/service1"

>>>>>>                - @Path annotation: @Path("service1") but then a

>>>>>> valid

>>>>>> request would be

>>>>>>> /services/service1/service1/<ID>'.

>>>>>> For both the 'address' attribute is relative to the servlet path.

>>>>>> The @Path Javadoc mentions that this path is relative to the

>>>>>> ApplicationPath which thus seems to be relative to the
>>>>>> jaxrs-server

>>>>>> address attribute. As for @Webservice it doesnn't seem to be

>>>>>> url-path

>>>> related.

>>>>>> Question: Because now address="/" is set for the jaxrs:server
>>>>>> will

>>>>>> it

>>>>>> also inspect requests targeted for the jaxws service as those

>>>>>> requests have start with the same path '/<basePath>/services/...'.

>>>>>> Albeit somewhat confusing.

>>>>>> J.P.

>>>>>> -----Original Message-----

>>>>>> From: Andriy Redko <dr...@gmail.com>

>>>>>> Sent: dinsdag 14 juni 2022 1:08

>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>>>>> issues@cxf.apache.org; dev@cxf.apache.org

>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi
>>>>>> Jean,

>>>>>> Indeed, the jaxrs:server does not expect address to be omitted,
>>>>>> you

>>>>>> could use the "/" (and I believe an empty string would also make it):

>>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...

>>>>>> </jaxrs:server>

>>>>>> Thank you.

>>>>>> Hope it helps.

>>>>>> Best Regards,

>>>>>>     Andriy Redko

>>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean

>>>>>>> declarations

>>>>>>> like:

>>>>>>>      <jaxrs:server id="restServer" basePackages="xxx">

>>>>>>>            <jaxrs:serviceBeans>

>>>>>>>                 <ref bean="TestApi" />

>>>>>>>            </jaxrs:serviceBeans>

>>>>>>>            <jaxrs:providers>

>>>>>>>                 <…/>

>>>>>>>            </jaxrs:providers>

>>>>>>>            <jaxrs:features>

>>>>>>>                 <… />

>>>>>>>            </jaxrs:features>

>>>>>>>            <jaxrs:inInterceptors>

>>>>>>>                 <… />

>>>>>>>            </jaxrs:inInterceptors>

>>>>>>>            <jaxrs:outInterceptors>*

>>>>>>>                 <**…**/>*

>>>>>>>            </jaxrs:outInterceptors>*

>>>>>>>      </jaxrs:server>


>>>>>>> Here my “TestApi” bean interface is declared like:

>>>>>>>       @Path("accounts")

>>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)

>>>>>>>        @Produces(MediaType.*APPLICATION_JSON*)

>>>>>>>        public interface TestApi {

>>>>>>>          …

>>>>>>>        }

>>>>>>> And CXF is triggered via a servlet configuration like:

>>>>>>>      <servlet>

>>>>>>>              <display-name>CXF Servlet</display-name>

>>>>>>>              <servlet-name>CXFServlet</servlet-name>

>>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</serv
>>>>>>> l
>>>>>>> e

>>>>>>> t


>>>>>>>        </servlet>

>>>>>>>        <servlet-mapping>

>>>>>>>              <servlet-name>CXFServlet</servlet-name>

>>>>>>>              <url-pattern>/services/*</url-pattern>

>>>>>>>        </servlet-mapping>


>>>>>>> Because I’ve got the @Path declaration on the interface type
>>>>>>> I’ve

>>>>>>> omitted

>>>>>>> the address=”accounts” attribute on the jaxrs:server declaration

>>>>>>> since otherwise

>>>>>>> I noticed that the server would be listening to

>>>>>>> /basepath/services/ accounts/accounts/…).

>>>>>>> Now this configuration works perfectly, only when shutting down

>>>>>>> the application server cxf calls

>>>>>>>         ServerImpl#destroy()

>>>>>>> which delegates (via Obeservable) to

>>>>>>> AbstractHTTPDestination#deactivate()

>>>>>>> which calls

>>>>>>> registry.removeDestination(path).

>>>>>>> This path is null (no ‘address’ specified on jaxrs:server

>>>>>>> declaration) and results in a NPE on the registry Map.

>>>>>>> This causes an unclean shutdown of my server.

>>>>>>> Is this an error in cxf or is my jaxrs:server configured
>>>>>>> incorrectly?

>>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration

>>>>>>> correctly interact with the @Path parameter on the API interface?

>>>> <<...>>


Re: Handle Bearer authorization

Posted by Andriy Redko <dr...@gmail.com>.
Hi Jean,
 
Apologies since I am rarely touching this part of the project, and do have some knowledge 
gaps there. Anyway, the flow I was sure should work actually does not [1] apparently. There 
are 2 security contexts actually: 

 - javax.ws.rs.core.SecurityContext (or jakarta.ws.rs.core.SecurityContext)
 - org.apache.cxf.security.SecurityContext

I was thinking about the latter but due to [1], the injection does not work. Could you
try to use javax.ws.rs.core.SecurityContext instead please to see what is being injected 
to you? 

Thank you.
 
[1] https://issues.apache.org/jira/browse/CXF-5803
  
Best Regards,
    Andriy Redko

> I did a test where I:
> - created my own SecurityContext implementation
> - in my authentication filter I construct an instance 'sc' of this
> SecurityContext and put in the message using:
> JAXRSUtils.getCurrentMessage().put(SecurityContext.class, sc);

> I tried two ways to obtain this SecurityContext my service methods:
>  1. using annotations:
>         Interface:                 Response
> getOnderneming(@HeaderParam("X-KMO-OPERATION-ID") UUID
> operationId,@PathParam("kboNr")  String kboNr,@Context SecurityContext sc);
>         Implementation:    Response getOnderneming(UUID operationId, String kboNr,
> SecurityContext sc){...}  2.without annotations:
>         Interface:                 Response
> getOnderneming(@HeaderParam("X-KMO-OPERATION-ID") UUID
> operationId,@PathParam("kboNr")  String kboNr);
>         Implementation:    Response getOnderneming(UUID operationId, String kboNr,
> SecurityContext sc){
>                                 SecurityContext sc =
> JAXRSUtils.getCurrentMessage().get(SecurityContext.class);
>                                 ...
>                              }Using the annotations (1. above) way doesn't work the
> SecurityContext object
> 'sc' is null on entering the getOnderneming() method.
> Without annotations  (2. Above) I do get a valid SecurityContext object
> 'sc'.

> Isn't the 'annotations'-way supposed to work this way?

> Regards,

> J.P. Urkens

> -----Original Message-----
> From: Jean Pierre URKENS <je...@devoteam.com>
> Sent: vrijdag 2 juni 2023 10:18
> To: 'Andriy Redko' <dr...@gmail.com>
> Subject: RE: Handle Bearer authorization

> Hi Andriy,

> As far as I understand the filters JwtAuthenticationFilter and
> AbstractJwtAuthenticationFilter the assumption is that a request is received
> with an 'Authentication' header that contains a signed JWT token. The filter
> provides in methods to:
> -  validate the signed JWT token
> - to create a SecurityContext (JwtTokenSecurityContext) from it.

> This isn't the situation I am dealing with. I am receiving a request with an
> 'Authorization' header containing 'Bearer <access_token>'. I've no knowledge
> about the nature of this access_token, nor do I need to since validating
> this access token is done by sending a request to an 'OAuth/OIDC
> introspection endpoint' passing on this access_token. The introspection
> endpoint replies with a scope object (JWT claims object) if the token is
> valid.

> Now I can deal with this situation and create my own SecurityContext
> (extended from ClaimsSecurityContext). What I don't understand is how I get
> this SecurityContext available in my service method.

> I see that the AbstractJwtAuthenticationFilter (line 56) puts the
> constructed SecurityContext in the Message:
>         if (securityContext != null) {
>                 JAXRSUtils.getCurrentMessage().put(SecurityContext.class,
> securityContext);
>         }

> Can I simply retrieve this in my service method by calling:
>         SecurityContext sc =
> JAXRSUtils.getCurrentMessage().get(SecurityContext.class);

> So no need to add  @Context annotations to service methods like e.g.:

> Interface:                 Response
> getOnderneming(@HeaderParam("X-KMO-OPERATION-ID") UUID
> operationId,@PathParam("kboNr")  String kboNr,@Context SecurityContext ctx);
> Implementation:    Response getOnderneming(UUID operationId, String kboNr,
> SecurityContext sc){...}

> Regards,

> J.P.
> -----Original Message-----
> From: Andriy Redko <dr...@gmail.com>
> Sent: vrijdag 2 juni 2023 0:29
> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev List
> <de...@cxf.apache.org>
> Subject: Re: Handle Bearer authorization

> Hi Jean,

> You should be able to get access to the Bearer and claims using
> JwtAuthenticationFilter + @Context SecurityContext The expected type of the
> security context should be ClaimsSecurityContext, with collection of claims
> being available.
> If the JwtAuthenticationFilter does not work for you (for some reasons), you
> could subclass AbstractJwtAuthenticationFilter.
> Hope it helps, thank you.

> Best Regards,
>     Andriy Redko

>> Hi Andriy,

>> I am lost in JAXRS JOSE security to figure out how to handle bearer
>> authorization. So what I currently did is:
>>   1. I created an ContainerRequestFilter to retrieve the Bearer access
>> token from the request and query the introspection endpoint which
>> returns the JWTClaims
>>   2.I added this filter in the Ininterceptor chain

>> This works, i.e. the filter is hit and it queries the introspection
>> endpoint which returns JWTClaims. The problem is that I need these
>> claims available in my service methods and I don't know how to pass
>> them from the ContainerRequestFilter to my service method. Thus far I
>> have been looking to save the JWTClaims as a property in the
>> ContainerRequestContext  which is available in my filter and inject
>> this context in my service methods with the @Context annotation. As
>> documented in
>> https://cxf.apache.org/docs/jax-rs-basics.html#JAXRSBasics-Contextanno
>> tations a number of context types can be injected with the @Context
>> annotation but I am not sure I can inject a ContainerRequestContext.

>> So I annotated my interface method as:
>>                 Response getOnderneming(
>>                         @HeaderParam("X-KMO-OPERATION-ID")
>> @NotNull(message="ERROR_2121") UUID operationId,
>>                         @PathParam("kboNr")
>> @NotNull(message="ERROR_2119") @Pattern(regexp =
>> "^\\d{10}$",message="ERROR_2216") String kboNr,
>>                         @Context ContainerRequestContext ctx);  And my
>> implementation method as:
>>                 Response getOnderneming(UUID operationId, String
>> kboNr, ContainerRequestContext ctx)

>> Unfortunately the ctx=null when the implementation method is called.

>> So my questions are:
>>  1.Is there a way to get the ContainerRequestContext available in my
>> service methods?
>>  2.If the answer to '1.' Is no how do I pass information constructed
>> in request filters to my service methods?
>>  3.Generally, is this the correct way to handle bearer authorization?
>> There is a lot of stuff in cxf-rt-rs-security-jose-(jaxrs) but I can't
>> really figure out how to use it. Anyway it is not sufficient for me to
>> have a filter that validates the bearer token. I need the associated
>> 'scope'
>> information in my service method as it contains information I'll need
>> in my business methods.

>> Regards,

>> J.P. Urkens

>> -----Original Message-----
>> From: Jean Pierre URKENS <je...@devoteam.com>
>> Sent: donderdag 25 mei 2023 9:48
>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'
>> <de...@cxf.apache.org>
>> Subject: RE: How to setup multiple JAXRS server endpoints

>> Hi Andriy,

>> The issue seems to be that the Reader is scanning the implementation
>> classes while the @SwaggerDefinition (and all other swagger
>> annotations) were on the interface class.

>> So
>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-j
>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L171,
>> scanning for @SwaggerDefinition, doesn't get triggered.
>> However via
>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-j
>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L176,
>> through reflection, the remaining swagger annotation information is
>> retrieved, just not the @SwaggerDefinition.

>> So, I moved the @SwaggerDefintion to the implementation class and now
>> it is ok.

>> Thanks for the advice,

>> J.P.

>> -----Original Message-----
>> From: Andriy Redko <dr...@gmail.com>
>> Sent: donderdag 25 mei 2023 2:27
>> To: Jean Pierre URKENS <je...@devoteam.com>;
>> dev@cxf.apache.org
>> Subject: Re: How to setup multiple JAXRS server endpoints

>> Hi Jean,

>> You may run into Swagger JAX-RS scanner limitations, as far as I can
>> tell - it checks class annotations for SwaggerDefinition, does not
>> traverse the hierarchy [1].

>> [1]
>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-j
>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194

>> Best Regards,
>>     Andriy Redko

>>>  RE: How to setup multiple JAXRS server endpoints

>>> Still one question );

>>> The generated swagger file doesn’t take into account the
>>> @SwaggerDefintion on my interface classes?

>>> As a test I looked at
>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma
>>> in/release/samples/jax_rs/description_swagger2_web**
>>> and** modified** sample2*
>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma
>>> in/release/samples/jax_rs/description_swagger2_web
>>> and modified sample2> as follows:

>>>    @Path("/sample2")

>>>       @Api(value = "/sample2",authorizations=
>>>       {@Authorization(value="bearer")},description = "Sample2

>> (modified) JAX-RS
>>>       service with Swagger documentation")

>>>       @SwaggerDefinition(

>>>               info = @Info(

>>>                       description = "Sample2 server",

>>>                       version="1.0",

>>>                       title = "Test2",

>>>                       contact = @Contact(name = "J.P. Urkens",email = "
>>>       *jean-pierre.urkens@devoteam.com*

>> <je...@devoteam.com>
>>>       ")),

>>>               securityDefinition =
>>>       @SecurityDefinition(apiKeyAuthDefinitions=

>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="Au
>> thorization",description="Use*
>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer
>>>       &lt;accessToken&gt;'")})

>>>       )

>>>       public class Sample2 {...}

>>> This correctly generates the ‘securityDefintions’ in the swagger file.

>>> If include the same @SwaggerDefinition and the authorizations on the
>>> @Api annotation as above in my interface classes then the generated
>>> swagger file doesn’t contain the ‘securityDefintions’ ?

>>> Any idea what I might be missing?

>>> Regards,

>>> J.P.

>>> -----Original Message-----
>>> From: Jean Pierre URKENS <je...@devoteam.com>
>>> Sent: dinsdag 23 mei 2023 12:52
>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <

>>> Subject: RE: How to setup multiple JAXRS server endpoints

>>> Hi Andriy,

>>> I added the parameter usePathBasedConfig=true to the Swagger2Feature
>>> bean declarations but still it does generate an empty swagger.yaml
>>> for interfaces KmopResources and KmopDienstverlener although I
>>> noticed that for these interfaces the
>>> @Path() annotation was commented out (as I included it in the server
>>> declaration). After providing an empty @Path("") declaration on

>> the API interface classes everything worked.

>>> Thanks for the support.

>>> -----Original Message-----

>>> From: Andriy Redko <dr...@gmail.com>

>>> Sent: dinsdag 23 mei 2023 3:42

>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>>> dev@cxf.apache.org

>>> Subject: Re: How to setup multiple JAXRS server endpoints

>>> Hi Jean,

>>> The main problem to configure Swagger property in your particular
>>> case is that the server address is not "known" or "introspectable"
>>> for

>> Swagger.
>>> Intuitively, it has to be set manually using basePath to the,
>>> essentially, the server address

>>> part:

>>>  - /op/services/accounts

>>>  - /op/services/resources

>>>  - /op/services/dienstverlener

>>> You could read more about other Swagger properties you have asked here:
>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte
>>> gration-and-Configuration#configuration-properties

>>> You definitely need to set usePathBasedConfig to "true" otherwise you
>>> will see the same Swagger specs for all servers. We have a sample
>>> here which uses 2 jaxrs:server

>>> instances:
>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai
>>> n/release/samples/jax_rs/description_swagger2_web

>>> Regarding SwaggerUI, I think the value for each of those should be
>>> set to,
>>> respectively:

>>>  - /op/services/accounts/swagger.yaml

>>>  - /op/services/resources/swagger.yaml

>>>  - /op/services/dienstverlener/swagger.yaml

>>> I believe this is matching your settings already, except the
>>> usePathBasedConfig part. The example referred above could be helpful,
>>> my apologies if I missed something, there are quite a lot of
>>> questions :-) The fact that the generated Swagger specification is
>>> empty is unexpected - it should not happen when JAX-RS resources are

>> properly configured.

>>> Thank you.

>>> Best Regards,

>>>     Andriy Redko

>>>>  RE: How to setup multiple JAXRS server endpoints

>>>> Hi Andriy,

>>>> I am not quite understanding how to correctly configure the

>>> Swagger2Feature.

>>>> Referring to the attached cxf-endpoints configuration I (as a
>>>> test)

>>>> created

>>>> 3 JAXRS server instances:

>>>> 1.      A* KmopApiServer* server for the*

>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving

>>>> requests for URI path:

>>>>        * <protocol>**//<host:<port>/op/services/accounts*

>>>>    ‘op’  = root path of the web application

>>>>             ‘services’ = servlet path of the CXF-servlet

>>>>       The address of the server is set to ‘/accounts’ and the
>>>> @Path(…)

>>>>       annotation on the interface class was cleared.

>>>> 2.      A* Kmop**Resources**ApiServer* server for the*

>> be.dvtm.aeo.op.*

>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving

>>>> requests for URI path:

>>>>        * <protocol>**//<host:<port>/op/services/**resources*

>>>> The address of the server is set to ‘/resources’ and the @Path(…)

>>>> annotation on the interface class was cleared.

>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*

>>> be.dvtm.aeo.op.*

>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving

>>>> requests for URI path:

>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*

>>>> The address of the server is set to ‘/dienstverlener’ and the

>>>> @Path(…) annotation on the interface class was cleared.

>>>> For each of these server instances I’ve set the Swagger2Feature

>>>> with configuration as indicated in the attached cxf-endpoints.xml.

>>>> With regard to the configurations for the Swagger2Feature I’ve the

>>>> following questions:

>>>> a)      Referring to

>> *https://cxf.apache.org/docs/swagger2feature.html*

>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you

>>>> clarify on the following configuration parameters:

>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘

>>>> /op/services’) or to the JAX-RS server instance (e.g.

>>>> ‘/op/services/accounts’) or still something else? Is it used to

>>>> resolve service classes or is it just for documentation in the
>>>> swagger

>>> file?

>>>> *ii.    ** resourcePackage* – the description mentions ‘package names’

>>>> while the default mentions ‘service classes’? Service 2 and 3 above

>>>> are within the same package (generated from the same yaml

>>>> specification that included both interfaces).

>>>> *iii.   ** ig**noreRoutes* – is this taken into account when

>>>> scanAllResources=false?

>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter

>> value

>>>> (cf. question ‘a’)?

>>>> b)      What would be the correct URL to generate a swagger.yaml file

>>> for

>>>> each of the above interfaces? Initially I called:

>>>> *i.     **

>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*

>>>> *ii.    **

>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*

>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*

>>>> *lener/swagger.yaml*

>>>>    All three requests delivered the same yaml specification, namely

>>> the one

>>>>       for interface* KmopApiServer*?

>>>> c)      I tried to debug the processing of the requests under ‘b)’ and

>>> this

>>>> is done by the class JAXRSInterceptor#processRequest where the

>>>> MessageImpl object for request “ii.” looks like the one attached.

>>>> It finds 3 resource

>>>> classes:

>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl

>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource

>>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService

>>>> è       It matches the request to resource*

>>> Swagger2ApiListingResource* with

>>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*

>>>> process(…)* method.

>>>> è       Here it seems to go wrong. It generates a

>> SwaggerContextService

>>>> having basePath=/op/services/resources/,swaggerConfig=null,

>>>> usePathBasedConfig=null and then calls

>>>> SwaggerContextService.getSwagger()

>>>> which returns the Swagger definition for interface KmopApiServer?

>>>> It looks like it caches generated swagger definitions based on a

>>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the

>>>> same for all 3 interfaces as usePathBasedConfig=null

>>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is

>>>> derived from the ServletConfig parameter

>>>> ‘swagger.use.path.based.config’.* So should this be set on the

>>>> declaration of the CXFServlet** in web.xml?*

>>>> è       Actually the SwaggerConfig, the JaxrsScanner and the generated

>>> Swagger

>>>> are cached using keys like

>>>> ‘swagger.config.id.[default|baseUriPath]’, ‘

>>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’

>>> is only done when usePathBasedconfig=true.

>>>> è       If I patch this to true then configIdKey=’

>>>> swagger.config.id./op/services/resources/’ and no swagger entry is

>>>> cached for this key so it will generate a new one. Again by

>>>> patching

>>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru
>>>> e

>>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”

>>>> è       Again Scanners are cached and if usePathBasedConfig=null it

>>> will use

>>>> the one cached under  ‘swagger.scanner.id.default’ and this again

>>>> returns the swagger definition for the KmopApiService interface.

>>>> è       So patching usePathBasedConfig=true will return a new one

>>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner

>>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘

>>>> which is correct. It will generate a new (but empty) Swagger object.

>>>> è       Next Swagger2ApiListingResource will call the

>>>> customizer.customize(s), which still isn’t putting anything new in

>>>> the Swagger object. Should it or should the next step do this?

>>>> è       Next BaseApiListingResource#getListing(…) is called which on

>>> its

>>>> turn calls getListingYamlResponse(..)

>>>> è       The final result is a swagger.yaml document with following

>>> content:

>>>>    swagger: "2.0"

>>>>       info:

>>>>         license:

>>>>           name: "Apache 2.0 License"

>>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html

>>>>       basePath: "/op/services/resources"

>>>>        So basically an empty swagger file.

>>>> d)      The usePathBasedConfig is derived from the ServletConfig

>>> parameter ‘

>>>> swagger.use.path.based.config’. Without this parameter set to true

>>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger

>>>> object.* So should this be set on the declaration of the

>>>> CXFServlet** in web.xml?*

>>>> The majority in this processing happens in the library

>>>> swagger-jaxrs-v1.6.10 which is included as a dependency on

>>> cxf-rt-rs-service-description-swagger.

>>>> Even if I patch usePathBasedConfig=true about everywhere where I

>>>> met this it still doesn’t generate a correct swagger.yaml. Am I

>>>> still missing some configuration parameter?

>>>> Any suggestions on how to resolve this would be welcome.

>>>> Regards,

>>>> J.P. Urkens










>>>> <<...>> <<...>>

>>>> -----Original Message-----

>>>> From: Andriy Redko <dr...@gmail.com>

>>>> Sent: maandag 8 mei 2023 23:15

>>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev

>>>> List <


>>>> Subject: Re: How to setup multiple JAXRS server endpoints

>>>> Hi Jean,

>>>> Indeed the way you would like to do that is somewhat tricky.

>>>>> So I tried to keep the @Path declaration on the interface classes
>>>>> but

>>>> changed them to @Path(“”). That does seems to work except the

>>>> swagger stuff no longer correctly works.

>>>> This is one of the possible options but OpenAPI/Swagger gets

>>>> confused for a

>>>> reason: the path is now implicit (not in the spec).

>>>> So how about this option:

>>>>  - use only one JAX-RS server (address "/")

>>>>  - host both resources but use @Path("accounts") and

>>>> @Path("resources") on them respectively


>>>> I see that for @Path("accounts") you need to apply the

>>>> "kmopApiAuthorizationFilter", that could be done using

>>>> DynamicFeature [1], [2]. If this is not the option and you would

>>>> prefer to use 2 separate JAX-RS servers, you may need to provide

>>>> your own instance of Swagger2Customizer [3], [4] which allows to

>>>> transform the OpenAPI/Swagger on the fly. Please let me know if that

>>> would it work for you, thank you.

>>>> [1]

>>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic
>>>> F

>>>> eature.html

>>>> [2]

>>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born
>>>> -

>>>> equal.html

>>>> [3]

>>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger
>>>> /

>>>> Swagger2Customizer.html

>>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has

>>>> customizer

>>>> property)


>>>> Best Regards,

>>>>     Andriy Redko

>>>>> Hi Andriy,

>>>>> I am again getting into trouble with server endpoint declarations.

>>>>> Now

>>>> because I am adding additional JAX-RS endpoints.

>>>>> The issue is with:

>>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration in

>>>> combination with

>>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the web.xml

>>>> in combination with

>>>>> 3.      The @Path declaration in the interface class in combination
>>>>> with

>>>>> 4.      The @Path declaration on the interface method in combination
>>>>> with

>>>>> So what I had is that my web application deployed under baseUlr 'op'

>>>>> had

>>>> one JAXRS server endpoint with declarations like:

>>>>> 1.      <jaxrs:server id="restServer"

>>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">

>>>>> 2.      <url-pattern>/services/*</url-pattern>

>>>>> 3.      @Path("accounts") on the public interface class

>>>>> 4.      @Path("/{authorisationId}/customerFund") on the customerFund

>>>> interface method

>>>>> A valid API call would thus be e.g.:

>>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/cu
>>>>> s
>>>>> t

>>>>> o

>>>>> merFund

>>>>> And this works correctly.

>>>>> We're now introducing additional JAX-RS service endpoints and now I

>>>>> am

>>>> running into problems. This second endpoint was declared with:

>>>>> 1.      <jaxrs:server id="resourceServer"

>>>> basePackages="be.dvtm.aeo.op.resources" address="/">

>>>>> 2.      <url-pattern>/services/*</url-pattern>

>>>>> 3.      @Path("resources") on the public interface class

>>>>> 4.      @Path("/NACE") on the NACE interface method

>>>>> So here a valid API call woud be:

>>>> https://<hostname>:<port>/op/services/resources/NACE.

>>>>> The problem is that I can not declare two <jaxrs:server> entries
>>>>> with

>>>>> the

>>>> same ‘address’ as it throws the exception:

>>>>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:

>>>> There is an endpoint already running on /.

>>>>>  So I tried changing the addresses to:

>>>>> ·       address=”accounts” for the restServer

>>>>> ·       address=”resources” for the resourceServer

>>>>> But to keep the API-call URLs the same I removed the @Path

>>>>> declaration on

>>>> the interface classes. By doing so the <jaxrs:server> bean

>>>> declarations no longer loads successfully.

>>>>> So I tried to keep the @Path declaration on the interface classes
>>>>> but

>>>> changed them to @Path(“”). That does seems to work except the

>>>> swagger stuff no longer correctly works.

>>>>> So what is the decent way to setup multiple JAX-RS server endpoints

>>>>> where

>>>> each server has its own configuration regarding supported features:

>>>>> ·       own validation

>>>>> ·       own object and exception mappings

>>>>> ·       own swagger file generation

>>>>> ·       own logging (in separate file if possible)

>>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in

>>>>> cooperation

>>>> with swager-ui v4.5.0.

>>>>> Below the declarations of my endpoints <<...>> Thanks for any advice.

>>>>> Regards,

>>>>> J.P. Urkens

>>>>> -----Original Message-----

>>>>> From: Andriy Redko <dr...@gmail.com>

>>>>> Sent: zaterdag 18 juni 2022 1:12

>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>>>> issues@cxf.apache.org; dev@cxf.apache.org

>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,

>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'

>>>>> Correct, so in the relative form like address="/<something>", the

>>>>> JAX-RS

>>>> endpoint path would be:

>>>>>     <baseUrl>/<servlet path

>>>>>> /<address>/[@ApplicationPath]/[@Path]

>>>>> The @ApplicationPath is optional in this case.

>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'

>>>>> The JAX-WS is very different from JAX-RS, essentially the action

>>>>> comes

>>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/

>>>> (@Path / @ApplicationPath are not relevant there).

>>>>>> Question: Because now address="/" is set for the jaxrs:server will

>>>>>> it

>>>>>> also inspect requests targeted for the jaxws service as those

>>>>>> requests have start with the same path '/<basePath>/services/...

>>>>> This is a good question, I have not done it myself but I think it

>>>>> should

>>>> work:

>>>>> the servlet dispatches according to registered services, in this

>>>>> regard

>>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?

>>> Thank you.

>>>>> Best Regards,

>>>>>     Andriy Redko

>>>>>> Hi Andriy,

>>>>>> Using address="/" seems to work but still I don't understand how
>>>>>> the

>>>>>> following work together:

>>>>>>  - path specification in servlet mapping for the CXF servlet

>>>>>> (org.apache.cxf.transport.servlet.CXFServlet)

>>>>>>  - the 'address' attribute on the jaxrs:server bean declaration

>>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the

>>>>>> service API description Say I've two services with (relateive to
>>>>>> the

>>>>>> host) url's:

>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'

>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'

>>>>>> How do I configure above 3 aspects? Currently I have (working):

>>>>>> 1.for the jaxrs:server endpoint:

>>>>>>         - servlet path mapping: '/services/*'

>>>>>>                - jaxrs-server address attribute: address="/"

>>>>>>                - @Path annotation: @Path("service1") 2.For the
>>>>>> jaxws

>>>>>> service endpoint:

>>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS

>>>>>> requests are handleb by the same CXF servle)

>>>>>>                - jaxws:endpoint server address attribute:

>>>>>> address="/service2"

>>>>>>                - @WebService(name="service2") A correct request
>>>>>> for

>>>>>> '1' would be '/basePath>/services/service1/<ID>'.

>>>>>> A correct request for '2' would be '/basePath>/services/service2'.

>>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:

>>>>>>         - the server address attribute

>>>>>>         - The API annotation (@Path or @Webservice) The JAXWS
>>>>>> server

>>>>>> address attribute doesn't seem to interfere with the @Webservice

>>>>>> annotation. While the jaxrs server address attribute does seem to

>>>>>> interfere with the @Path annotation. I would have expected the
>>>>>> jaxrs

>>>>>> server aspects to be configured as:

>>>>>>         - servlet path mapping: '/services/*'

>>>>>>                - jaxrs-server address attribute: address="/service1"

>>>>>>                - @Path annotation: @Path("service1") but then a

>>>>>> valid

>>>>>> request would be

>>>>>>> /services/service1/service1/<ID>'.

>>>>>> For both the 'address' attribute is relative to the servlet path.

>>>>>> The @Path Javadoc mentions that this path is relative to the

>>>>>> ApplicationPath which thus seems to be relative to the
>>>>>> jaxrs-server

>>>>>> address attribute. As for @Webservice it doesnn't seem to be

>>>>>> url-path

>>>> related.

>>>>>> Question: Because now address="/" is set for the jaxrs:server will

>>>>>> it

>>>>>> also inspect requests targeted for the jaxws service as those

>>>>>> requests have start with the same path '/<basePath>/services/...'.

>>>>>> Albeit somewhat confusing.

>>>>>> J.P.

>>>>>> -----Original Message-----

>>>>>> From: Andriy Redko <dr...@gmail.com>

>>>>>> Sent: dinsdag 14 juni 2022 1:08

>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>>>>> issues@cxf.apache.org; dev@cxf.apache.org

>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi
>>>>>> Jean,

>>>>>> Indeed, the jaxrs:server does not expect address to be omitted,
>>>>>> you

>>>>>> could use the "/" (and I believe an empty string would also make it):

>>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...

>>>>>> </jaxrs:server>

>>>>>> Thank you.

>>>>>> Hope it helps.

>>>>>> Best Regards,

>>>>>>     Andriy Redko

>>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean

>>>>>>> declarations

>>>>>>> like:

>>>>>>>      <jaxrs:server id="restServer" basePackages="xxx">

>>>>>>>            <jaxrs:serviceBeans>

>>>>>>>                 <ref bean="TestApi" />

>>>>>>>            </jaxrs:serviceBeans>

>>>>>>>            <jaxrs:providers>

>>>>>>>                 <…/>

>>>>>>>            </jaxrs:providers>

>>>>>>>            <jaxrs:features>

>>>>>>>                 <… />

>>>>>>>            </jaxrs:features>

>>>>>>>            <jaxrs:inInterceptors>

>>>>>>>                 <… />

>>>>>>>            </jaxrs:inInterceptors>

>>>>>>>            <jaxrs:outInterceptors>*

>>>>>>>                 <**…**/>*

>>>>>>>            </jaxrs:outInterceptors>*

>>>>>>>      </jaxrs:server>


>>>>>>> Here my “TestApi” bean interface is declared like:

>>>>>>>       @Path("accounts")

>>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)

>>>>>>>        @Produces(MediaType.*APPLICATION_JSON*)

>>>>>>>        public interface TestApi {

>>>>>>>          …

>>>>>>>        }

>>>>>>> And CXF is triggered via a servlet configuration like:

>>>>>>>      <servlet>

>>>>>>>              <display-name>CXF Servlet</display-name>

>>>>>>>              <servlet-name>CXFServlet</servlet-name>

>>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servl
>>>>>>> e

>>>>>>> t


>>>>>>>        </servlet>

>>>>>>>        <servlet-mapping>

>>>>>>>              <servlet-name>CXFServlet</servlet-name>

>>>>>>>              <url-pattern>/services/*</url-pattern>

>>>>>>>        </servlet-mapping>


>>>>>>> Because I’ve got the @Path declaration on the interface type I’ve

>>>>>>> omitted

>>>>>>> the address=”accounts” attribute on the jaxrs:server declaration

>>>>>>> since otherwise

>>>>>>> I noticed that the server would be listening to

>>>>>>> /basepath/services/ accounts/accounts/…).

>>>>>>> Now this configuration works perfectly, only when shutting down

>>>>>>> the application server cxf calls

>>>>>>>         ServerImpl#destroy()

>>>>>>> which delegates (via Obeservable) to

>>>>>>> AbstractHTTPDestination#deactivate()

>>>>>>> which calls

>>>>>>> registry.removeDestination(path).

>>>>>>> This path is null (no ‘address’ specified on jaxrs:server

>>>>>>> declaration) and results in a NPE on the registry Map.

>>>>>>> This causes an unclean shutdown of my server.

>>>>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?

>>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration

>>>>>>> correctly interact with the @Path parameter on the API interface?

>>>> <<...>>


Re: Handle Bearer authorization

Posted by Andriy Redko <dr...@gmail.com>.
Hi Jean,
 
You should be able to get access to the Bearer and claims using JwtAuthenticationFilter + @Context SecurityContext
The expected type of the security context should be ClaimsSecurityContext, with collection of claims being available. 
If the JwtAuthenticationFilter does not work for you (for some reasons), you could subclass AbstractJwtAuthenticationFilter.
Hope it helps, thank you.

Best Regards,
    Andriy Redko
        
> Hi Andriy,

> I am lost in JAXRS JOSE security to figure out how to handle bearer
> authorization. So what I currently did is:
>   1. I created an ContainerRequestFilter to retrieve the Bearer access token
> from the request and query the introspection endpoint which returns the
> JWTClaims
>   2.I added this filter in the Ininterceptor chain

> This works, i.e. the filter is hit and it queries the introspection endpoint
> which returns JWTClaims. The problem is that I need these claims available
> in my service methods and I don't know how to pass them from the
> ContainerRequestFilter to my service method. Thus far I have been looking to
> save the JWTClaims as a property in the ContainerRequestContext  which is
> available in my filter and inject this context in my service methods with
> the @Context annotation. As documented in
> https://cxf.apache.org/docs/jax-rs-basics.html#JAXRSBasics-Contextannotations a
> number of context types can be injected with the @Context annotation but I
> am not sure I can inject a ContainerRequestContext.

> So I annotated my interface method as:
>                 Response getOnderneming(
>                         @HeaderParam("X-KMO-OPERATION-ID") @NotNull(message="ERROR_2121") UUID
> operationId,
>                         @PathParam("kboNr") @NotNull(message="ERROR_2119") @Pattern(regexp =
> "^\\d{10}$",message="ERROR_2216") String kboNr,
>                         @Context ContainerRequestContext ctx);
>  And my implementation method as:
>                 Response getOnderneming(UUID operationId, String kboNr,
> ContainerRequestContext ctx)

> Unfortunately the ctx=null when the implementation method is called.

> So my questions are:
>  1.Is there a way to get the ContainerRequestContext available in my service
> methods?
>  2.If the answer to '1.' Is no how do I pass information constructed in
> request filters to my service methods?
>  3.Generally, is this the correct way to handle bearer authorization? There
> is a lot of stuff in cxf-rt-rs-security-jose-(jaxrs) but I can't really
> figure out how to use it. Anyway it is not sufficient for me to have a
> filter that validates the bearer token. I need the associated 'scope'
> information in my service method as it contains information I'll need in my
> business methods.

> Regards,

> J.P. Urkens

> -----Original Message-----
> From: Jean Pierre URKENS <je...@devoteam.com>
> Sent: donderdag 25 mei 2023 9:48
> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'
> <de...@cxf.apache.org>
> Subject: RE: How to setup multiple JAXRS server endpoints

> Hi Andriy,

> The issue seems to be that the Reader is scanning the implementation classes
> while the @SwaggerDefinition (and all other swagger annotations) were on the
> interface class.

> So
> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java#L171,
> scanning for @SwaggerDefinition, doesn't get triggered.
> However via
> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java#L176,
> through reflection, the remaining swagger annotation information is
> retrieved, just not the @SwaggerDefinition.

> So, I moved the @SwaggerDefintion to the implementation class and now it is
> ok.

> Thanks for the advice,

> J.P.

> -----Original Message-----
> From: Andriy Redko <dr...@gmail.com>
> Sent: donderdag 25 mei 2023 2:27
> To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
> Subject: Re: How to setup multiple JAXRS server endpoints

> Hi Jean,

> You may run into Swagger JAX-RS scanner limitations, as far as I can tell -
> it checks class annotations for SwaggerDefinition, does not traverse the
> hierarchy [1].

> [1]
> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java#L194

> Best Regards,
>     Andriy Redko

>>  RE: How to setup multiple JAXRS server endpoints

>> Still one question );

>> The generated swagger file doesn’t take into account the
>> @SwaggerDefintion on my interface classes?

>> As a test I looked at
>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma
>> in/release/samples/jax_rs/description_swagger2_web**
>> and** modified** sample2*
>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma
>> in/release/samples/jax_rs/description_swagger2_web
>> and modified sample2> as follows:

>>    @Path("/sample2")

>>       @Api(value = "/sample2",authorizations=
>>       {@Authorization(value="bearer")},description = "Sample2
> (modified) JAX-RS
>>       service with Swagger documentation")

>>       @SwaggerDefinition(

>>               info = @Info(

>>                       description = "Sample2 server",

>>                       version="1.0",

>>                       title = "Test2",

>>                       contact = @Contact(name = "J.P. Urkens",email = "
>>       *jean-pierre.urkens@devoteam.com*
> <je...@devoteam.com>
>>       ")),

>>               securityDefinition =
>>       @SecurityDefinition(apiKeyAuthDefinitions=
> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="Authorization",description="Use*
>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer
>>       &lt;accessToken&gt;'")})

>>       )

>>       public class Sample2 {...}

>> This correctly generates the ‘securityDefintions’ in the swagger file.

>> If include the same @SwaggerDefinition and the authorizations on
>> the @Api annotation as above in my interface classes then the
>> generated swagger file doesn’t contain the ‘securityDefintions’ ?

>> Any idea what I might be missing?

>> Regards,

>> J.P.

>> -----Original Message-----
>> From: Jean Pierre URKENS <je...@devoteam.com>
>> Sent: dinsdag 23 mei 2023 12:52
>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <

>> Subject: RE: How to setup multiple JAXRS server endpoints

>> Hi Andriy,

>> I added the parameter usePathBasedConfig=true to the
>> Swagger2Feature bean declarations but still it does generate an
>> empty swagger.yaml for interfaces KmopResources and
>> KmopDienstverlener although I noticed that for these interfaces the
>> @Path() annotation was commented out (as I included it in the
>> server declaration). After providing an empty @Path("") declaration on
> the API interface classes everything worked.

>> Thanks for the support.

>> -----Original Message-----

>> From: Andriy Redko <dr...@gmail.com>

>> Sent: dinsdag 23 mei 2023 3:42

>> To: Jean Pierre URKENS <je...@devoteam.com>;
>> dev@cxf.apache.org

>> Subject: Re: How to setup multiple JAXRS server endpoints

>> Hi Jean,

>> The main problem to configure Swagger property in your particular
>> case is that the server address is not "known" or "introspectable" for
> Swagger.
>> Intuitively, it has to be set manually using basePath to the,
>> essentially, the server address

>> part:

>>  - /op/services/accounts

>>  - /op/services/resources

>>  - /op/services/dienstverlener

>> You could read more about other Swagger properties you have asked here:
>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte
>> gration-and-Configuration#configuration-properties

>> You definitely need to set usePathBasedConfig to "true" otherwise
>> you will see the same Swagger specs for all servers. We have a
>> sample here which uses 2 jaxrs:server

>> instances:
>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai
>> n/release/samples/jax_rs/description_swagger2_web

>> Regarding SwaggerUI, I think the value for each of those should be
>> set to,
>> respectively:

>>  - /op/services/accounts/swagger.yaml

>>  - /op/services/resources/swagger.yaml

>>  - /op/services/dienstverlener/swagger.yaml

>> I believe this is matching your settings already, except the
>> usePathBasedConfig part. The example referred above could be
>> helpful, my apologies if I missed something, there are quite a lot
>> of questions :-) The fact that the generated Swagger specification
>> is empty is unexpected - it should not happen when JAX-RS resources are
> properly configured.

>> Thank you.

>> Best Regards,

>>     Andriy Redko

>>>  RE: How to setup multiple JAXRS server endpoints

>>> Hi Andriy,

>>> I am not quite understanding how to correctly configure the

>> Swagger2Feature.

>>> Referring to the attached cxf-endpoints configuration I (as a
>>> test)

>>> created

>>> 3 JAXRS server instances:

>>> 1.      A* KmopApiServer* server for the*

>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving

>>> requests for URI path:

>>>        * <protocol>**//<host:<port>/op/services/accounts*

>>>    ‘op’  = root path of the web application

>>>             ‘services’ = servlet path of the CXF-servlet

>>>       The address of the server is set to ‘/accounts’ and the
>>> @Path(…)

>>>       annotation on the interface class was cleared.

>>> 2.      A* Kmop**Resources**ApiServer* server for the*
> be.dvtm.aeo.op.*

>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving

>>> requests for URI path:

>>>        * <protocol>**//<host:<port>/op/services/**resources*

>>> The address of the server is set to ‘/resources’ and the @Path(…)

>>> annotation on the interface class was cleared.

>>> 3.      A* Kmop**Dienstverlener**Server* server for the*

>> be.dvtm.aeo.op.*

>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving

>>> requests for URI path:

>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*

>>> The address of the server is set to ‘/dienstverlener’ and the

>>> @Path(…) annotation on the interface class was cleared.

>>> For each of these server instances I’ve set the Swagger2Feature

>>> with configuration as indicated in the attached cxf-endpoints.xml.

>>> With regard to the configurations for the Swagger2Feature I’ve the

>>> following questions:

>>> a)      Referring to
> *https://cxf.apache.org/docs/swagger2feature.html*

>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you

>>> clarify on the following configuration parameters:

>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘

>>> /op/services’) or to the JAX-RS server instance (e.g.

>>> ‘/op/services/accounts’) or still something else? Is it used to

>>> resolve service classes or is it just for documentation in the
>>> swagger

>> file?

>>> *ii.    ** resourcePackage* – the description mentions ‘package names’

>>> while the default mentions ‘service classes’? Service 2 and 3
>>> above

>>> are within the same package (generated from the same yaml

>>> specification that included both interfaces).

>>> *iii.   ** ig**noreRoutes* – is this taken into account when

>>> scanAllResources=false?

>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter
> value

>>> (cf. question ‘a’)?

>>> b)      What would be the correct URL to generate a swagger.yaml file

>> for

>>> each of the above interfaces? Initially I called:

>>> *i.     **

>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*

>>> *ii.    **

>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*

>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*

>>> *lener/swagger.yaml*

>>>    All three requests delivered the same yaml specification,
>>> namely

>> the one

>>>       for interface* KmopApiServer*?

>>> c)      I tried to debug the processing of the requests under ‘b)’ and

>> this

>>> is done by the class JAXRSInterceptor#processRequest where the

>>> MessageImpl object for request “ii.” looks like the one attached.

>>> It finds 3 resource

>>> classes:

>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl

>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource

>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService

>>> è       It matches the request to resource*

>> Swagger2ApiListingResource* with

>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*

>>> process(…)* method.

>>> è       Here it seems to go wrong. It generates a
> SwaggerContextService

>>> having basePath=/op/services/resources/,swaggerConfig=null,

>>> usePathBasedConfig=null and then calls

>>> SwaggerContextService.getSwagger()

>>> which returns the Swagger definition for interface KmopApiServer?

>>> It looks like it caches generated swagger definitions based on a

>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the

>>> same for all 3 interfaces as usePathBasedConfig=null

>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is

>>> derived from the ServletConfig parameter

>>> ‘swagger.use.path.based.config’.* So should this be set on the

>>> declaration of the CXFServlet** in web.xml?*

>>> è       Actually the SwaggerConfig, the JaxrsScanner and the generated

>> Swagger

>>> are cached using keys like

>>> ‘swagger.config.id.[default|baseUriPath]’, ‘

>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’

>> is only done when usePathBasedconfig=true.

>>> è       If I patch this to true then configIdKey=’

>>> swagger.config.id./op/services/resources/’ and no swagger entry is

>>> cached for this key so it will generate a new one. Again by

>>> patching

>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru
>>> e

>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”

>>> è       Again Scanners are cached and if usePathBasedConfig=null it

>> will use

>>> the one cached under  ‘swagger.scanner.id.default’ and this again

>>> returns the swagger definition for the KmopApiService interface.

>>> è       So patching usePathBasedConfig=true will return a new one

>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner

>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘

>>> which is correct. It will generate a new (but empty) Swagger object.

>>> è       Next Swagger2ApiListingResource will call the

>>> customizer.customize(s), which still isn’t putting anything new in

>>> the Swagger object. Should it or should the next step do this?

>>> è       Next BaseApiListingResource#getListing(…) is called which on

>> its

>>> turn calls getListingYamlResponse(..)

>>> è       The final result is a swagger.yaml document with following

>> content:

>>>    swagger: "2.0"

>>>       info:

>>>         license:

>>>           name: "Apache 2.0 License"

>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html

>>>       basePath: "/op/services/resources"

>>>        So basically an empty swagger file.

>>> d)      The usePathBasedConfig is derived from the ServletConfig

>> parameter ‘

>>> swagger.use.path.based.config’. Without this parameter set to true

>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger

>>> object.* So should this be set on the declaration of the

>>> CXFServlet** in web.xml?*

>>> The majority in this processing happens in the library

>>> swagger-jaxrs-v1.6.10 which is included as a dependency on

>> cxf-rt-rs-service-description-swagger.

>>> Even if I patch usePathBasedConfig=true about everywhere where I

>>> met this it still doesn’t generate a correct swagger.yaml. Am I

>>> still missing some configuration parameter?

>>> Any suggestions on how to resolve this would be welcome.

>>> Regards,

>>> J.P. Urkens










>>> <<...>> <<...>>

>>> -----Original Message-----

>>> From: Andriy Redko <dr...@gmail.com>

>>> Sent: maandag 8 mei 2023 23:15

>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev

>>> List <


>>> Subject: Re: How to setup multiple JAXRS server endpoints

>>> Hi Jean,

>>> Indeed the way you would like to do that is somewhat tricky.

>>>> So I tried to keep the @Path declaration on the interface classes
>>>> but

>>> changed them to @Path(“”). That does seems to work except the

>>> swagger stuff no longer correctly works.

>>> This is one of the possible options but OpenAPI/Swagger gets

>>> confused for a

>>> reason: the path is now implicit (not in the spec).

>>> So how about this option:

>>>  - use only one JAX-RS server (address "/")

>>>  - host both resources but use @Path("accounts") and

>>> @Path("resources") on them respectively


>>> I see that for @Path("accounts") you need to apply the

>>> "kmopApiAuthorizationFilter", that could be done using

>>> DynamicFeature [1], [2]. If this is not the option and you would

>>> prefer to use 2 separate JAX-RS servers, you may need to provide

>>> your own instance of Swagger2Customizer [3], [4] which allows to

>>> transform the OpenAPI/Swagger on the fly. Please let me know if
>>> that

>> would it work for you, thank you.

>>> [1]

>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic
>>> F

>>> eature.html

>>> [2]

>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born
>>> -

>>> equal.html

>>> [3]

>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger
>>> /

>>> Swagger2Customizer.html

>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has

>>> customizer

>>> property)


>>> Best Regards,

>>>     Andriy Redko

>>>> Hi Andriy,

>>>> I am again getting into trouble with server endpoint declarations.

>>>> Now

>>> because I am adding additional JAX-RS endpoints.

>>>> The issue is with:

>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration in

>>> combination with

>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the web.xml

>>> in combination with

>>>> 3.      The @Path declaration in the interface class in combination with

>>>> 4.      The @Path declaration on the interface method in combination
>>>> with

>>>> So what I had is that my web application deployed under baseUlr 'op'

>>>> had

>>> one JAXRS server endpoint with declarations like:

>>>> 1.      <jaxrs:server id="restServer"

>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">

>>>> 2.      <url-pattern>/services/*</url-pattern>

>>>> 3.      @Path("accounts") on the public interface class

>>>> 4.      @Path("/{authorisationId}/customerFund") on the customerFund

>>> interface method

>>>> A valid API call would thus be e.g.:

>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/cus
>>>> t

>>>> o

>>>> merFund

>>>> And this works correctly.

>>>> We're now introducing additional JAX-RS service endpoints and now I

>>>> am

>>> running into problems. This second endpoint was declared with:

>>>> 1.      <jaxrs:server id="resourceServer"

>>> basePackages="be.dvtm.aeo.op.resources" address="/">

>>>> 2.      <url-pattern>/services/*</url-pattern>

>>>> 3.      @Path("resources") on the public interface class

>>>> 4.      @Path("/NACE") on the NACE interface method

>>>> So here a valid API call woud be:

>>> https://<hostname>:<port>/op/services/resources/NACE.

>>>> The problem is that I can not declare two <jaxrs:server> entries
>>>> with

>>>> the

>>> same ‘address’ as it throws the exception:

>>>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:

>>> There is an endpoint already running on /.

>>>>  So I tried changing the addresses to:

>>>> ·       address=”accounts” for the restServer

>>>> ·       address=”resources” for the resourceServer

>>>> But to keep the API-call URLs the same I removed the @Path

>>>> declaration on

>>> the interface classes. By doing so the <jaxrs:server> bean

>>> declarations no longer loads successfully.

>>>> So I tried to keep the @Path declaration on the interface classes
>>>> but

>>> changed them to @Path(“”). That does seems to work except the

>>> swagger stuff no longer correctly works.

>>>> So what is the decent way to setup multiple JAX-RS server endpoints

>>>> where

>>> each server has its own configuration regarding supported features:

>>>> ·       own validation

>>>> ·       own object and exception mappings

>>>> ·       own swagger file generation

>>>> ·       own logging (in separate file if possible)

>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in

>>>> cooperation

>>> with swager-ui v4.5.0.

>>>> Below the declarations of my endpoints <<...>> Thanks for any advice.

>>>> Regards,

>>>> J.P. Urkens

>>>> -----Original Message-----

>>>> From: Andriy Redko <dr...@gmail.com>

>>>> Sent: zaterdag 18 juni 2022 1:12

>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>>> issues@cxf.apache.org; dev@cxf.apache.org

>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,

>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'

>>>> Correct, so in the relative form like address="/<something>", the

>>>> JAX-RS

>>> endpoint path would be:

>>>>     <baseUrl>/<servlet path

mapping>>>>>/<address>/[@ApplicationPath]/[@Path]

>>>> The @ApplicationPath is optional in this case.

>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'

>>>> The JAX-WS is very different from JAX-RS, essentially the action

>>>> comes

>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/

>>> (@Path / @ApplicationPath are not relevant there).

>>>>> Question: Because now address="/" is set for the jaxrs:server will

>>>>> it

>>>>> also inspect requests targeted for the jaxws service as those

>>>>> requests have start with the same path '/<basePath>/services/...

>>>> This is a good question, I have not done it myself but I think it

>>>> should

>>> work:

>>>> the servlet dispatches according to registered services, in this

>>>> regard

>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?

>> Thank you.

>>>> Best Regards,

>>>>     Andriy Redko

>>>>> Hi Andriy,

>>>>> Using address="/" seems to work but still I don't understand how
>>>>> the

>>>>> following work together:

>>>>>  - path specification in servlet mapping for the CXF servlet

>>>>> (org.apache.cxf.transport.servlet.CXFServlet)

>>>>>  - the 'address' attribute on the jaxrs:server bean declaration

>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the

>>>>> service API description Say I've two services with (relateive to
>>>>> the

>>>>> host) url's:

>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'

>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'

>>>>> How do I configure above 3 aspects? Currently I have (working):

>>>>> 1.for the jaxrs:server endpoint:

>>>>>         - servlet path mapping: '/services/*'

>>>>>                - jaxrs-server address attribute: address="/"

>>>>>                - @Path annotation: @Path("service1") 2.For the
>>>>> jaxws

>>>>> service endpoint:

>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS

>>>>> requests are handleb by the same CXF servle)

>>>>>                - jaxws:endpoint server address attribute:

>>>>> address="/service2"

>>>>>                - @WebService(name="service2") A correct request for

>>>>> '1' would be '/basePath>/services/service1/<ID>'.

>>>>> A correct request for '2' would be '/basePath>/services/service2'.

>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:

>>>>>         - the server address attribute

>>>>>         - The API annotation (@Path or @Webservice) The JAXWS
>>>>> server

>>>>> address attribute doesn't seem to interfere with the @Webservice

>>>>> annotation. While the jaxrs server address attribute does seem to

>>>>> interfere with the @Path annotation. I would have expected the
>>>>> jaxrs

>>>>> server aspects to be configured as:

>>>>>         - servlet path mapping: '/services/*'

>>>>>                - jaxrs-server address attribute: address="/service1"

>>>>>                - @Path annotation: @Path("service1") but then a

>>>>> valid

>>>>> request would be

>>>>>> /services/service1/service1/<ID>'.

>>>>> For both the 'address' attribute is relative to the servlet path.

>>>>> The @Path Javadoc mentions that this path is relative to the

>>>>> ApplicationPath which thus seems to be relative to the jaxrs-server

>>>>> address attribute. As for @Webservice it doesnn't seem to be

>>>>> url-path

>>> related.

>>>>> Question: Because now address="/" is set for the jaxrs:server will

>>>>> it

>>>>> also inspect requests targeted for the jaxws service as those

>>>>> requests have start with the same path '/<basePath>/services/...'.

>>>>> Albeit somewhat confusing.

>>>>> J.P.

>>>>> -----Original Message-----

>>>>> From: Andriy Redko <dr...@gmail.com>

>>>>> Sent: dinsdag 14 juni 2022 1:08

>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>>>> issues@cxf.apache.org; dev@cxf.apache.org

>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,

>>>>> Indeed, the jaxrs:server does not expect address to be omitted, you

>>>>> could use the "/" (and I believe an empty string would also make it):

>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...

>>>>> </jaxrs:server>

>>>>> Thank you.

>>>>> Hope it helps.

>>>>> Best Regards,

>>>>>     Andriy Redko

>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean

>>>>>> declarations

>>>>>> like:

>>>>>>      <jaxrs:server id="restServer" basePackages="xxx">

>>>>>>            <jaxrs:serviceBeans>

>>>>>>                 <ref bean="TestApi" />

>>>>>>            </jaxrs:serviceBeans>

>>>>>>            <jaxrs:providers>

>>>>>>                 <…/>

>>>>>>            </jaxrs:providers>

>>>>>>            <jaxrs:features>

>>>>>>                 <… />

>>>>>>            </jaxrs:features>

>>>>>>            <jaxrs:inInterceptors>

>>>>>>                 <… />

>>>>>>            </jaxrs:inInterceptors>

>>>>>>            <jaxrs:outInterceptors>*

>>>>>>                 <**…**/>*

>>>>>>            </jaxrs:outInterceptors>*

>>>>>>      </jaxrs:server>


>>>>>> Here my “TestApi” bean interface is declared like:

>>>>>>       @Path("accounts")

>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)

>>>>>>        @Produces(MediaType.*APPLICATION_JSON*)

>>>>>>        public interface TestApi {

>>>>>>          …

>>>>>>        }

>>>>>> And CXF is triggered via a servlet configuration like:

>>>>>>      <servlet>

>>>>>>              <display-name>CXF Servlet</display-name>

>>>>>>              <servlet-name>CXFServlet</servlet-name>

>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servle

>>>>>> t


>>>>>>        </servlet>

>>>>>>        <servlet-mapping>

>>>>>>              <servlet-name>CXFServlet</servlet-name>

>>>>>>              <url-pattern>/services/*</url-pattern>

>>>>>>        </servlet-mapping>


>>>>>> Because I’ve got the @Path declaration on the interface type I’ve

>>>>>> omitted

>>>>>> the address=”accounts” attribute on the jaxrs:server declaration

>>>>>> since otherwise

>>>>>> I noticed that the server would be listening to

>>>>>> /basepath/services/ accounts/accounts/…).

>>>>>> Now this configuration works perfectly, only when shutting down

>>>>>> the application server cxf calls

>>>>>>         ServerImpl#destroy()

>>>>>> which delegates (via Obeservable) to

>>>>>> AbstractHTTPDestination#deactivate()

>>>>>> which calls

>>>>>> registry.removeDestination(path).

>>>>>> This path is null (no ‘address’ specified on jaxrs:server

>>>>>> declaration) and results in a NPE on the registry Map.

>>>>>> This causes an unclean shutdown of my server.

>>>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?

>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration

>>>>>> correctly interact with the @Path parameter on the API interface?

>>> <<...>>


RE: How to setup multiple JAXRS server endpoints

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
Hi Andriy,

The issue seems to be that the Reader is scanning the implementation classes
while the @SwaggerDefinition (and all other swagger annotations) were on the
interface class.

So
https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java#L171,
scanning for @SwaggerDefinition, doesn't get triggered.
However via
https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java#L176,
through reflection,
the remaining swagger annotation information is retrieved, just not the
@SwaggerDefinition.

So, I moved the @SwaggerDefintion to the implementation class and now it is
ok.

Thanks for the advice,

J.P.

-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: donderdag 25 mei 2023 2:27
To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
Subject: Re: How to setup multiple JAXRS server endpoints

Hi Jean,

You may run into Swagger JAX-RS scanner limitations, as far as I can tell -
it checks class annotations for SwaggerDefinition, does not traverse the
hierarchy [1].

[1]
https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java#L194

Best Regards,
    Andriy Redko

JPU>  RE: How to setup multiple JAXRS server endpoints

JPU> Still one question );

JPU> The generated swagger file doesn’t take into account the
JPU> @SwaggerDefintion on my interface classes?

JPU> As a test I looked at
JPU> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma
JPU> in/release/samples/jax_rs/description_swagger2_web**
JPU> and** modified** sample2*
JPU> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma
JPU> in/release/samples/jax_rs/description_swagger2_web
JPU> and modified sample2> as follows:

JPU>    @Path("/sample2")

JPU>       @Api(value = "/sample2",authorizations=
JPU>       {@Authorization(value="bearer")},description = "Sample2
(modified) JAX-RS
JPU>       service with Swagger documentation")

JPU>       @SwaggerDefinition(

JPU>               info = @Info(

JPU>                       description = "Sample2 server",

JPU>                       version="1.0",

JPU>                       title = "Test2",

JPU>                       contact = @Contact(name = "J.P. Urkens",email = "
JPU>       *jean-pierre.urkens@devoteam.com*
<je...@devoteam.com>
JPU>       ")),

JPU>               securityDefinition =
JPU>       @SecurityDefinition(apiKeyAuthDefinitions=
JPU>
*{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="Authorization",description="Use*
JPU>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer
JPU>       &lt;accessToken&gt;'")})

JPU>       )

JPU>       public class Sample2 {...}

JPU> This correctly generates the ‘securityDefintions’ in the swagger file.

JPU> If include the same @SwaggerDefinition and the authorizations on
JPU> the @Api annotation as above in my interface classes then the
JPU> generated swagger file doesn’t contain the ‘securityDefintions’ ?

JPU> Any idea what I might be missing?

JPU> Regards,

JPU> J.P.

JPU> -----Original Message-----
JPU> From: Jean Pierre URKENS <je...@devoteam.com>
JPU> Sent: dinsdag 23 mei 2023 12:52
JPU> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <
dev@cxf.apache.org>>
JPU> Subject: RE: How to setup multiple JAXRS server endpoints

JPU> Hi Andriy,

JPU> I added the parameter usePathBasedConfig=true to the
JPU> Swagger2Feature bean declarations but still it does generate an
JPU> empty swagger.yaml for interfaces KmopResources and
JPU> KmopDienstverlener although I noticed that for these interfaces the
JPU> @Path() annotation was commented out (as I included it in the
JPU> server declaration). After providing an empty @Path("") declaration on
the API interface classes everything worked.

JPU> Thanks for the support.

JPU> -----Original Message-----

JPU> From: Andriy Redko <dr...@gmail.com>

JPU> Sent: dinsdag 23 mei 2023 3:42

JPU> To: Jean Pierre URKENS <je...@devoteam.com>;
JPU> dev@cxf.apache.org

JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

JPU> The main problem to configure Swagger property in your particular
JPU> case is that the server address is not "known" or "introspectable" for
Swagger.
JPU> Intuitively, it has to be set manually using basePath to the,
JPU> essentially, the server address

JPU> part:

JPU>  - /op/services/accounts

JPU>  - /op/services/resources

JPU>  - /op/services/dienstverlener

JPU> You could read more about other Swagger properties you have asked here:
JPU> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte
JPU> gration-and-Configuration#configuration-properties

JPU> You definitely need to set usePathBasedConfig to "true" otherwise
JPU> you will see the same Swagger specs for all servers. We have a
JPU> sample here which uses 2 jaxrs:server

JPU> instances:
JPU> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai
JPU> n/release/samples/jax_rs/description_swagger2_web

JPU> Regarding SwaggerUI, I think the value for each of those should be
JPU> set to,
JPU> respectively:

JPU>  - /op/services/accounts/swagger.yaml

JPU>  - /op/services/resources/swagger.yaml

JPU>  - /op/services/dienstverlener/swagger.yaml

JPU> I believe this is matching your settings already, except the
JPU> usePathBasedConfig part. The example referred above could be
JPU> helpful, my apologies if I missed something, there are quite a lot
JPU> of questions :-) The fact that the generated Swagger specification
JPU> is empty is unexpected - it should not happen when JAX-RS resources are
properly configured.

JPU> Thank you.

JPU> Best Regards,

JPU>     Andriy Redko

JPU>>  RE: How to setup multiple JAXRS server endpoints

JPU>> Hi Andriy,

JPU>> I am not quite understanding how to correctly configure the
JPU> Swagger2Feature.

JPU>> Referring to the attached cxf-endpoints configuration I (as a
JPU>> test)

JPU>> created

JPU>> 3 JAXRS server instances:

JPU>> 1.      A* KmopApiServer* server for the*

JPU>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving

JPU>> requests for URI path:

JPU>>        * <protocol>**//<host:<port>/op/services/accounts*

JPU>>    ‘op’  = root path of the web application

JPU>>             ‘services’ = servlet path of the CXF-servlet

JPU>>       The address of the server is set to ‘/accounts’ and the
JPU>> @Path(…)

JPU>>       annotation on the interface class was cleared.

JPU>> 2.      A* Kmop**Resources**ApiServer* server for the*
be.dvtm.aeo.op.*

JPU>> *openapi.**api.Kmop**Recources**ApiService* interface, serving

JPU>> requests for URI path:

JPU>>        * <protocol>**//<host:<port>/op/services/**resources*

JPU>> The address of the server is set to ‘/resources’ and the @Path(…)

JPU>> annotation on the interface class was cleared.

JPU>> 3.      A* Kmop**Dienstverlener**Server* server for the*
JPU> be.dvtm.aeo.op.*

JPU>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving

JPU>> requests for URI path:

JPU>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*

JPU>> The address of the server is set to ‘/dienstverlener’ and the

JPU>> @Path(…) annotation on the interface class was cleared.

JPU>> For each of these server instances I’ve set the Swagger2Feature

JPU>> with configuration as indicated in the attached cxf-endpoints.xml.

JPU>> With regard to the configurations for the Swagger2Feature I’ve the

JPU>> following questions:

JPU>> a)      Referring to
*https://cxf.apache.org/docs/swagger2feature.html*

JPU>> <https://cxf.apache.org/docs/swagger2feature.html>  could you

JPU>> clarify on the following configuration parameters:

JPU>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘

JPU>> /op/services’) or to the JAX-RS server instance (e.g.

JPU>> ‘/op/services/accounts’) or still something else? Is it used to

JPU>> resolve service classes or is it just for documentation in the
JPU>> swagger
JPU> file?

JPU>> *ii.    ** resourcePackage* – the description mentions ‘package names’

JPU>> while the default mentions ‘service classes’? Service 2 and 3
JPU>> above

JPU>> are within the same package (generated from the same yaml

JPU>> specification that included both interfaces).

JPU>> *iii.   ** ig**noreRoutes* – is this taken into account when

JPU>> scanAllResources=false?

JPU>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter
value

JPU>> (cf. question ‘a’)?

JPU>> b)      What would be the correct URL to generate a swagger.yaml file
JPU> for

JPU>> each of the above interfaces? Initially I called:

JPU>> *i.     **
JPU> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*

JPU>> *ii.    **
JPU> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*

JPU>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*

JPU>> *lener/swagger.yaml*

JPU>>    All three requests delivered the same yaml specification,
JPU>> namely
JPU> the one

JPU>>       for interface* KmopApiServer*?

JPU>> c)      I tried to debug the processing of the requests under ‘b)’ and
JPU> this

JPU>> is done by the class JAXRSInterceptor#processRequest where the

JPU>> MessageImpl object for request “ii.” looks like the one attached.

JPU>> It finds 3 resource

JPU>> classes:

JPU>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl

JPU>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource

JPU>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService

JPU>> è       It matches the request to resource*
JPU> Swagger2ApiListingResource* with

JPU>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*

JPU>> process(…)* method.

JPU>> è       Here it seems to go wrong. It generates a
SwaggerContextService

JPU>> having basePath=/op/services/resources/,swaggerConfig=null,

JPU>> usePathBasedConfig=null and then calls

JPU>> SwaggerContextService.getSwagger()

JPU>> which returns the Swagger definition for interface KmopApiServer?

JPU>> It looks like it caches generated swagger definitions based on a

JPU>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the

JPU>> same for all 3 interfaces as usePathBasedConfig=null

JPU>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is

JPU>> derived from the ServletConfig parameter

JPU>> ‘swagger.use.path.based.config’.* So should this be set on the

JPU>> declaration of the CXFServlet** in web.xml?*

JPU>> è       Actually the SwaggerConfig, the JaxrsScanner and the generated
JPU> Swagger

JPU>> are cached using keys like

JPU>> ‘swagger.config.id.[default|baseUriPath]’, ‘

JPU>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’
JPU> is only done when usePathBasedconfig=true.

JPU>> è       If I patch this to true then configIdKey=’

JPU>> swagger.config.id./op/services/resources/’ and no swagger entry is

JPU>> cached for this key so it will generate a new one. Again by

JPU>> patching

JPU>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru
JPU>> e

JPU>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”

JPU>> è       Again Scanners are cached and if usePathBasedConfig=null it
JPU> will use

JPU>> the one cached under  ‘swagger.scanner.id.default’ and this again

JPU>> returns the swagger definition for the KmopApiService interface.

JPU>> è       So patching usePathBasedConfig=true will return a new one

JPU>> (DefaultJaxrsScanner). The classes to scan for in this new scanner

JPU>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘

JPU>> which is correct. It will generate a new (but empty) Swagger object.

JPU>> è       Next Swagger2ApiListingResource will call the

JPU>> customizer.customize(s), which still isn’t putting anything new in

JPU>> the Swagger object. Should it or should the next step do this?

JPU>> è       Next BaseApiListingResource#getListing(…) is called which on
JPU> its

JPU>> turn calls getListingYamlResponse(..)

JPU>> è       The final result is a swagger.yaml document with following
JPU> content:

JPU>>    swagger: "2.0"

JPU>>       info:

JPU>>         license:

JPU>>           name: "Apache 2.0 License"

JPU>>           url: http://www.apache.org/licenses/LICENSE-2.0.html

JPU>>       basePath: "/op/services/resources"

JPU>>        So basically an empty swagger file.

JPU>> d)      The usePathBasedConfig is derived from the ServletConfig
JPU> parameter ‘

JPU>> swagger.use.path.based.config’. Without this parameter set to true

JPU>> there will be only one Swaggerconfig, JaxrsScanner and Swagger

JPU>> object.* So should this be set on the declaration of the

JPU>> CXFServlet** in web.xml?*

JPU>> The majority in this processing happens in the library

JPU>> swagger-jaxrs-v1.6.10 which is included as a dependency on
JPU> cxf-rt-rs-service-description-swagger.

JPU>> Even if I patch usePathBasedConfig=true about everywhere where I

JPU>> met this it still doesn’t generate a correct swagger.yaml. Am I

JPU>> still missing some configuration parameter?

JPU>> Any suggestions on how to resolve this would be welcome.

JPU>> Regards,

JPU>> J.P. Urkens










JPU>> <<...>> <<...>>

JPU>> -----Original Message-----

JPU>> From: Andriy Redko <dr...@gmail.com>

JPU>> Sent: maandag 8 mei 2023 23:15

JPU>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev

JPU>> List <

dev@cxf.apache.org>>>

JPU>> Subject: Re: How to setup multiple JAXRS server endpoints

JPU>> Hi Jean,

JPU>> Indeed the way you would like to do that is somewhat tricky.

>>> So I tried to keep the @Path declaration on the interface classes
>>> but

JPU>> changed them to @Path(“”). That does seems to work except the

JPU>> swagger stuff no longer correctly works.

JPU>> This is one of the possible options but OpenAPI/Swagger gets

JPU>> confused for a

JPU>> reason: the path is now implicit (not in the spec).

JPU>> So how about this option:

JPU>>  - use only one JAX-RS server (address "/")

JPU>>  - host both resources but use @Path("accounts") and

JPU>> @Path("resources") on them respectively


JPU>> I see that for @Path("accounts") you need to apply the

JPU>> "kmopApiAuthorizationFilter", that could be done using

JPU>> DynamicFeature [1], [2]. If this is not the option and you would

JPU>> prefer to use 2 separate JAX-RS servers, you may need to provide

JPU>> your own instance of Swagger2Customizer [3], [4] which allows to

JPU>> transform the OpenAPI/Swagger on the fly. Please let me know if
JPU>> that
JPU> would it work for you, thank you.

JPU>> [1]

JPU>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic
JPU>> F

JPU>> eature.html

JPU>> [2]

JPU>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born
JPU>> -

JPU>> equal.html

JPU>> [3]

JPU>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger
JPU>> /

JPU>> Swagger2Customizer.html

JPU>> [4] https://cxf.apache.org/docs/swagger2feature.html (has

JPU>> customizer

JPU>> property)


JPU>> Best Regards,

JPU>>     Andriy Redko

>>> Hi Andriy,

>>> I am again getting into trouble with server endpoint declarations.

>>> Now

JPU>> because I am adding additional JAX-RS endpoints.

>>> The issue is with:

>>> 1.      The 'address' attribute on the <jaxrs:server> declaration in

JPU>> combination with

>>> 2.      The 'url-pattern' for the CXFServlet declaration in the web.xml

JPU>> in combination with

>>> 3.      The @Path declaration in the interface class in combination with

>>> 4.      The @Path declaration on the interface method in combination
>>> with

>>> So what I had is that my web application deployed under baseUlr 'op'

>>> had

JPU>> one JAXRS server endpoint with declarations like:

>>> 1.      <jaxrs:server id="restServer"

JPU>> basePackages="be.dvtm.aeo.op.sodexo" address="/">

>>> 2.      <url-pattern>/services/*</url-pattern>

>>> 3.      @Path("accounts") on the public interface class

>>> 4.      @Path("/{authorisationId}/customerFund") on the customerFund

JPU>> interface method

>>> A valid API call would thus be e.g.:

>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/cus
>>> t

>>> o

>>> merFund

>>> And this works correctly.

>>> We're now introducing additional JAX-RS service endpoints and now I

>>> am

JPU>> running into problems. This second endpoint was declared with:

>>> 1.      <jaxrs:server id="resourceServer"

JPU>> basePackages="be.dvtm.aeo.op.resources" address="/">

>>> 2.      <url-pattern>/services/*</url-pattern>

>>> 3.      @Path("resources") on the public interface class

>>> 4.      @Path("/NACE") on the NACE interface method

>>> So here a valid API call woud be:

JPU>> https://<hostname>:<port>/op/services/resources/NACE.

>>> The problem is that I can not declare two <jaxrs:server> entries
>>> with

>>> the

JPU>> same ‘address’ as it throws the exception:

>>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:

JPU>> There is an endpoint already running on /.

>>>  So I tried changing the addresses to:

>>> ·       address=”accounts” for the restServer

>>> ·       address=”resources” for the resourceServer

>>> But to keep the API-call URLs the same I removed the @Path

>>> declaration on

JPU>> the interface classes. By doing so the <jaxrs:server> bean

JPU>> declarations no longer loads successfully.

>>> So I tried to keep the @Path declaration on the interface classes
>>> but

JPU>> changed them to @Path(“”). That does seems to work except the

JPU>> swagger stuff no longer correctly works.

>>> So what is the decent way to setup multiple JAX-RS server endpoints

>>> where

JPU>> each server has its own configuration regarding supported features:

>>> ·       own validation

>>> ·       own object and exception mappings

>>> ·       own swagger file generation

>>> ·       own logging (in separate file if possible)

>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in

>>> cooperation

JPU>> with swager-ui v4.5.0.

>>> Below the declarations of my endpoints <<...>> Thanks for any advice.

>>> Regards,

>>> J.P. Urkens

>>> -----Original Message-----

>>> From: Andriy Redko <dr...@gmail.com>

>>> Sent: zaterdag 18 juni 2022 1:12

>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>> issues@cxf.apache.org; dev@cxf.apache.org

>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,

>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'

>>> Correct, so in the relative form like address="/<something>", the

>>> JAX-RS

JPU>> endpoint path would be:

>>>     <baseUrl>/<servlet path

>>> mapping>/<address>/[@ApplicationPath]/[@Path]

>>> The @ApplicationPath is optional in this case.

>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'

>>> The JAX-WS is very different from JAX-RS, essentially the action

>>> comes

JPU>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/

JPU>> (@Path / @ApplicationPath are not relevant there).

>>>> Question: Because now address="/" is set for the jaxrs:server will

>>>> it

>>>> also inspect requests targeted for the jaxws service as those

>>>> requests have start with the same path '/<basePath>/services/...

>>> This is a good question, I have not done it myself but I think it

>>> should

JPU>> work:

>>> the servlet dispatches according to registered services, in this

>>> regard

JPU>> JAX-RS and JAX-WS should not conflict. Does it work in your case?
JPU> Thank you.

>>> Best Regards,

>>>     Andriy Redko

>>>> Hi Andriy,

>>>> Using address="/" seems to work but still I don't understand how
>>>> the

>>>> following work together:

>>>>  - path specification in servlet mapping for the CXF servlet

>>>> (org.apache.cxf.transport.servlet.CXFServlet)

>>>>  - the 'address' attribute on the jaxrs:server bean declaration

>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the

>>>> service API description Say I've two services with (relateive to
>>>> the

>>>> host) url's:

>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'

>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'

>>>> How do I configure above 3 aspects? Currently I have (working):

>>>> 1.for the jaxrs:server endpoint:

>>>>         - servlet path mapping: '/services/*'

>>>>                - jaxrs-server address attribute: address="/"

>>>>                - @Path annotation: @Path("service1") 2.For the
>>>> jaxws

>>>> service endpoint:

>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS

>>>> requests are handleb by the same CXF servle)

>>>>                - jaxws:endpoint server address attribute:

>>>> address="/service2"

>>>>                - @WebService(name="service2") A correct request for

>>>> '1' would be '/basePath>/services/service1/<ID>'.

>>>> A correct request for '2' would be '/basePath>/services/service2'.

>>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:

>>>>         - the server address attribute

>>>>         - The API annotation (@Path or @Webservice) The JAXWS
>>>> server

>>>> address attribute doesn't seem to interfere with the @Webservice

>>>> annotation. While the jaxrs server address attribute does seem to

>>>> interfere with the @Path annotation. I would have expected the
>>>> jaxrs

>>>> server aspects to be configured as:

>>>>         - servlet path mapping: '/services/*'

>>>>                - jaxrs-server address attribute: address="/service1"

>>>>                - @Path annotation: @Path("service1") but then a

>>>> valid

>>>> request would be

>>>>> /services/service1/service1/<ID>'.

>>>> For both the 'address' attribute is relative to the servlet path.

>>>> The @Path Javadoc mentions that this path is relative to the

>>>> ApplicationPath which thus seems to be relative to the jaxrs-server

>>>> address attribute. As for @Webservice it doesnn't seem to be

>>>> url-path

JPU>> related.

>>>> Question: Because now address="/" is set for the jaxrs:server will

>>>> it

>>>> also inspect requests targeted for the jaxws service as those

>>>> requests have start with the same path '/<basePath>/services/...'.

>>>> Albeit somewhat confusing.

>>>> J.P.

>>>> -----Original Message-----

>>>> From: Andriy Redko <dr...@gmail.com>

>>>> Sent: dinsdag 14 juni 2022 1:08

>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>>> issues@cxf.apache.org; dev@cxf.apache.org

>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,

>>>> Indeed, the jaxrs:server does not expect address to be omitted, you

>>>> could use the "/" (and I believe an empty string would also make it):

>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...

>>>> </jaxrs:server>

>>>> Thank you.

>>>> Hope it helps.

>>>> Best Regards,

>>>>     Andriy Redko

>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean

>>>>> declarations

>>>>> like:

>>>>>      <jaxrs:server id="restServer" basePackages="xxx">

>>>>>            <jaxrs:serviceBeans>

>>>>>                 <ref bean="TestApi" />

>>>>>            </jaxrs:serviceBeans>

>>>>>            <jaxrs:providers>

>>>>>                 <…/>

>>>>>            </jaxrs:providers>

>>>>>            <jaxrs:features>

>>>>>                 <… />

>>>>>            </jaxrs:features>

>>>>>            <jaxrs:inInterceptors>

>>>>>                 <… />

>>>>>            </jaxrs:inInterceptors>

>>>>>            <jaxrs:outInterceptors>*

>>>>>                 <**…**/>*

>>>>>            </jaxrs:outInterceptors>*

>>>>>      </jaxrs:server>


>>>>> Here my “TestApi” bean interface is declared like:

>>>>>       @Path("accounts")

>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)

>>>>>        @Produces(MediaType.*APPLICATION_JSON*)

>>>>>        public interface TestApi {

>>>>>          …

>>>>>        }

>>>>> And CXF is triggered via a servlet configuration like:

>>>>>      <servlet>

>>>>>              <display-name>CXF Servlet</display-name>

>>>>>              <servlet-name>CXFServlet</servlet-name>

>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servle

>>>>> t

-class>>>>>>

>>>>>        </servlet>

>>>>>        <servlet-mapping>

>>>>>              <servlet-name>CXFServlet</servlet-name>

>>>>>              <url-pattern>/services/*</url-pattern>

>>>>>        </servlet-mapping>


>>>>> Because I’ve got the @Path declaration on the interface type I’ve

>>>>> omitted

>>>>> the address=”accounts” attribute on the jaxrs:server declaration

>>>>> since otherwise

>>>>> I noticed that the server would be listening to

>>>>> /basepath/services/ accounts/accounts/…).

>>>>> Now this configuration works perfectly, only when shutting down

>>>>> the application server cxf calls

>>>>>         ServerImpl#destroy()

>>>>> which delegates (via Obeservable) to

>>>>> AbstractHTTPDestination#deactivate()

>>>>> which calls

>>>>> registry.removeDestination(path).

>>>>> This path is null (no ‘address’ specified on jaxrs:server

>>>>> declaration) and results in a NPE on the registry Map.

>>>>> This causes an unclean shutdown of my server.

>>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?

>>>>> How does the ‘address’ attribute on the jaxrs:server declaration

>>>>> correctly interact with the @Path parameter on the API interface?

JPU>> <<...>>

Re: How to setup multiple JAXRS server endpoints

Posted by Andriy Redko <dr...@gmail.com>.
Hi Jean,

Everything looks as it should be so far, may I ask you please to (re)confirm that
you have SwaggerUI dependency included (fe 5.1.0 but any of 4.x should also work):

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>swagger-ui</artifactId>
            <version>5.1.0</version>
        </dependency>

Thank you.

Best Regards,
    Andriy Redko

JPU> Hi Andriy,



JPU> As a test I removed all JAX-RS endpoints that use Swagger v2 annotations
JPU> from my configuration file (see attachment).

JPU> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger v3
JPU> annotations, using the OpenApiFeature i.o. Swagger2Feature.

JPU> If I run my server with this configuration I only get the (working) *WADL*
JPU> and *OpenAPI* endpoints, no Swagger UI endpoint:





JPU> So there is some configuration missing to detect/activate the Swagger
JPU> endpoint. When I look at the samples that come with the distribution of CXF
JPU> (I am using v3.5.6) nothing special seems to be configured to activate this?

JPU> Do you have any idea how the SwaggerUiService is picked up when loading?



JPU> J.P.



JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: dinsdag 11 juli 2023 3:44
JPU> To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
JPU> Subject: Re: How to setup multiple JAXRS server endpoints



JPU> Hi Jean,



JPU> I guess you figured one issue, swagger.json -> openapi.json, but to be
JPU> honest we have never tested or envisioned the application that would use
JPU> OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same time, I am afraid this is
JPU> just not supported. You may get things back on track when going with
JPU> OpenAPI 3.0 for all services.



JPU> Thank you.



JPU> Best Regards,

JPU>     Andriy Redko





>> Hi Andriy,







>> I am trying to trace the difference in handling with another

>> application where I’ve got only one CXF service endpoint that uses

>> swagger v3 openapi annotations.



>> There I see that when handling the Swagger page request (

>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json) the

>> JAXRSInInterceptor is calling:







>> *JAXRSUtils.**getRootResources*(Message message)







>> It contains 4 entries:



>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint

>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService















>> On the application described below with the service ‘oidcsim’ when

>> calling the swagger page request

>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the

>> result of the getRootResources doesn’t contain the ClassResourceInfo ‘

>> SwaggerUiService’. It only contains 3 entries:



>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)

>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource







>> The SwaggerUiService is the one that is configured to handle the
JPU> ‘api-docs’

>> path-request. Since it is missing the request is tried to match with

>> the other two resources but fails, hence ‘NOT FOUND’ exception.







>> I can’t trace back where these rootResources are set and why the

>> SwaggerUiService’ isn’t listed.







>> J.P.



>> *From:* Jean Pierre URKENS <je...@devoteam.com>

>> *Sent:* maandag 10 juli 2023 13:43

>> *To:* 'Andriy Redko' <dr...@gmail.com>

>> *Subject:* RE: How to setup multiple JAXRS server endpoints







>> Andriy,







>> I am trying to switch from Swagger v2 to OpenApi v3 annotations

>> basically because my starting point is an OpenApi v3.0.7 yaml file

>> description and OpenAPI seems to be the way forward.



>> For applications where I have only one CXF JAX-RS endpoint exposed I

>> had no problems converting. However as soon as there are multiple

>> endpoints I run into troubles.







>> So, to recall, I've an application exposing 3 JAX-RS endpoints that

>> where previously annotated with swagger v2 annotations (i.e. package

>> io.swagger.annotations.*) which I migrated to



>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*). In

>> accordance I altered my CXF JAX-RS endpoint configuration from (only

>> showing relevant parts, see attachment for full setup):







>>                <!-- CXF Swagger2Feature -->



>>                <bean id="SwaggerUiConfigOidcApi"

>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>>                               <property name="queryConfigEnabled"



>>                               <property name="url"

>> value="/op/services/oidcsim/swagger.yaml"/>



>>                </bean>



>>                <bean id="Swagger2FeatureOidcApi"

>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">



>>                               <property name="basePath"

>> value="/op/services/oidcsim"/>



>>                               <property name="usePathBasedConfig"



>>                               <property name="resourcePackage"

>> value="be.dvtm.aeo.op.oidc"/>



>>                               <property name="supportSwaggerUi"



>>                               <property name="swaggerUiConfig"

>> ref="SwaggerUiConfigOidcApi"/>



>>                </bean>



>>                <jaxrs:server id="OidcProviderApiServer"

>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>>                               ....



>>                               <jaxrs:features>



>>                                              <ref

>> bean="Swagger2FeatureOidcApi" />



>>                               </jaxrs:features>



>>                               ...



>>                </jaxrs:server>







>> TO:



>>                <!-- CXF OpenAPIFeature -->



>>                <bean id="OidcSwaggerUiConfig"

>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>>                               <property name="queryConfigEnabled"



>>                               <property name="url"

>> value="openapi.json"/>



>>                </bean>



>>                <bean id="OidcOpenApiFeature"

>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">



>>                               <property name="supportSwaggerUi"



>>                               <property name="swaggerUiConfig"

>> ref="OidcSwaggerUiConfig"/>



>>                               <property name="swaggerUiVersion"



>>                               <property name="scan" value="false"/>



>>                               <property name="useContextBasedConfig"



>>                               <property name="resourcePackages"

>> value="be.dvtm.aeo.op.oidc"/>



>>                </bean>



>>                <jaxrs:server id="OidcProviderApiServer"

>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>>                               ....



>>                               <jaxrs:features>



>>                                              <ref
JPU> bean="OidcOpenApiFeature"



>>                               </jaxrs:features>



>>                               ...



>>                </jaxrs:server>











>> Now when starting my application and navigating to the root part "

>> http://localhost:localPort/op/services" I get an overview of all my

>> endpoints:







>> Now there are 3 RESTful service endpoints setup:



>>    1. ‘oidcsim’ which I switched to swagger v3 annotations

>>    2. ‘openapi’ currently still swagger v2 annotations

>>    3. ‘sdx’ currently still swagger v2 annotations







>> all endpoints work except for the ‘swagger endpoint address for the

>> oidcsim

>> endpoint:

>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services/oi

>> dcsim/swagger.json



>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*

>> endpoint of the oidcsim resource. I am getting an error (the value of

>> the ‘url’ query parameter isn’t relevant):







>>         “WebApplicationException has been caught, status: 404,

>> message: HTTP 404 Not Found”







>> When I try (without the ‘/oidcsim’ context):

>> http://l-p53-008:8081/op/services/api-docs I get:



>>                “No service was found.”







>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs

>> doesn’t exist, where as the endpoint

>> http://l-p53-008:8081/op/services/api-docs does exist but no service
JPU> description is found?



>> Of course my intention is to get working, as previously with the

>> swagger v2 setup for which I then specifically added the

>> *Swagger2Feature* config

>> parameters:



>>                               <property name="basePath"

>> value="/op/services/oidcsim"/>



>>                               <property name="usePathBasedConfig"







>> But I don’t find the according configuration options for the

>> *OpenApiFeature* class or whether I should configure this in another way.







>> Any suggestions on this?







>> Regards,







>> J.P.











>> -----Original Message-----

>> From: Andriy Redko <dr...@gmail.com>

>> Sent: donderdag 25 mei 2023 2:27

>> To: Jean Pierre URKENS <je...@devoteam.com>;

>> dev@cxf.apache.org

>> Subject: Re: How to setup multiple JAXRS server endpoints







>> Hi Jean,







>> You may run into Swagger JAX-RS scanner limitations, as far as I can

>> tell - it checks class annotations for SwaggerDefinition, does not

>> traverse the hierarchy [1].







>> [1]

>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-j

>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194







>> Best Regards,



>>     Andriy Redko







>>>  RE: How to setup multiple JAXRS server endpoints







>>> Still one question );







>>> The generated swagger file doesn’t take into account the



>>> @SwaggerDefintion on my interface classes?







>>> As a test I looked at



>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma



>>> in/release/samples/jax_rs/description_swagger2_web**



>>> and** modified** sample2*



>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma



>>> in/release/samples/jax_rs/description_swagger2_web



>>> and modified sample2> as follows:







>>>    @Path("/sample2")







>>>       @Api(value = "/sample2",authorizations=



>>>       {@Authorization(value="bearer")},description = "Sample2

>> (modified) JAX-RS



>>>       service with Swagger documentation")







>>>       @SwaggerDefinition(







>>>               info = @Info(







>>>                       description = "Sample2 server",







>>>                       version="1.0",







>>>                       title = "Test2",







>>>                       contact = @Contact(name = "J.P. Urkens",email = "



>>>       *jean-pierre.urkens@devoteam.com* <

>> jean-pierre.urkens@devoteam.com>



>>>       ")),







>>>               securityDefinition =



>>>       @SecurityDefinition(apiKeyAuthDefinitions=



>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="Au

>> thorization",description="Use*



>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer



>>>       &lt;accessToken&gt;'")})







>>>       )







>>>       public class Sample2 {...}







>>> This correctly generates the ‘securityDefintions’ in the swagger file.







>>> If include the same @SwaggerDefinition and the authorizations on



>>> the @Api annotation as above in my interface classes then the



>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?







>>> Any idea what I might be missing?







>>> Regards,







>>> J.P.







>>> -----Original Message-----



>>> From: Jean Pierre URKENS <je...@devoteam.com>



>>> Sent: dinsdag 23 mei 2023 12:52



>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <





>>> Subject: RE: How to setup multiple JAXRS server endpoints







>>> Hi Andriy,







>>> I added the parameter usePathBasedConfig=true to the



>>> Swagger2Feature bean declarations but still it does generate an



>>> empty swagger.yaml for interfaces KmopResources and



>>> KmopDienstverlener although I noticed that for these interfaces the



>>> @Path() annotation was commented out (as I included it in the



>>> server declaration). After providing an empty @Path("") declaration

>>> on

>> the API interface classes everything worked.







>>> Thanks for the support.







>>> -----Original Message-----







>>> From: Andriy Redko <dr...@gmail.com>







>>> Sent: dinsdag 23 mei 2023 3:42







>>> To: Jean Pierre URKENS <je...@devoteam.com>;



>>> dev@cxf.apache.org







>>> Subject: Re: How to setup multiple JAXRS server endpoints







>>> Hi Jean,







>>> The main problem to configure Swagger property in your particular



>>> case is that the server address is not "known" or "introspectable"

>>> for

>> Swagger.



>>> Intuitively, it has to be set manually using basePath to the,



>>> essentially, the server address







>>> part:







>>>  - /op/services/accounts







>>>  - /op/services/resources







>>>  - /op/services/dienstverlener







>>> You could read more about other Swagger properties you have asked here:



>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte



>>> gration-and-Configuration#configuration-properties







>>> You definitely need to set usePathBasedConfig to "true" otherwise



>>> you will see the same Swagger specs for all servers. We have a



>>> sample here which uses 2 jaxrs:server







>>> instances:



>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai



>>> n/release/samples/jax_rs/description_swagger2_web







>>> Regarding SwaggerUI, I think the value for each of those should be



>>> set to,



>>> respectively:







>>>  - /op/services/accounts/swagger.yaml







>>>  - /op/services/resources/swagger.yaml







>>>  - /op/services/dienstverlener/swagger.yaml







>>> I believe this is matching your settings already, except the



>>> usePathBasedConfig part. The example referred above could be



>>> helpful, my apologies if I missed something, there are quite a lot



>>> of questions :-) The fact that the generated Swagger specification



>>> is empty is unexpected - it should not happen when JAX-RS resources

>> are properly configured.







>>> Thank you.







>>> Best Regards,







>>>     Andriy Redko







>>>>  RE: How to setup multiple JAXRS server endpoints







>>>> Hi Andriy,







>>>> I am not quite understanding how to correctly configure the



>>> Swagger2Feature.







>>>> Referring to the attached cxf-endpoints configuration I (as a



>>>> test)







>>>> created







>>>> 3 JAXRS server instances:







>>>> 1.      A* KmopApiServer* server for the*







>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving







>>>> requests for URI path:







>>>>        * <protocol>**//<host:<port>/op/services/accounts*







>>>>    ‘op’  = root path of the web application







>>>>             ‘services’ = servlet path of the CXF-servlet







>>>>       The address of the server is set to ‘/accounts’ and the



>>>> @Path(…)







>>>>       annotation on the interface class was cleared.







>>>> 2.      A* Kmop**Resources**ApiServer* server for the*

>> be.dvtm.aeo.op.*







>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving







>>>> requests for URI path:







>>>>        * <protocol>**//<host:<port>/op/services/**resources*







>>>> The address of the server is set to ‘/resources’ and the @Path(…)







>>>> annotation on the interface class was cleared.







>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*



>>> be.dvtm.aeo.op.*







>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving







>>>> requests for URI path:







>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*







>>>> The address of the server is set to ‘/dienstverlener’ and the







>>>> @Path(…) annotation on the interface class was cleared.







>>>> For each of these server instances I’ve set the Swagger2Feature







>>>> with configuration as indicated in the attached cxf-endpoints.xml.







>>>> With regard to the configurations for the Swagger2Feature I’ve the







>>>> following questions:







>>>> a)      Referring to *

>> https://cxf.apache.org/docs/swagger2feature.html*







>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you







>>>> clarify on the following configuration parameters:







>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘







>>>> /op/services’) or to the JAX-RS server instance (e.g.







>>>> ‘/op/services/accounts’) or still something else? Is it used to







>>>> resolve service classes or is it just for documentation in the



>>>> swagger



>>> file?







>>>> *ii.    ** resourcePackage* – the description mentions ‘package names’







>>>> while the default mentions ‘service classes’? Service 2 and 3



>>>> above







>>>> are within the same package (generated from the same yaml







>>>> specification that included both interfaces).







>>>> *iii.   ** ig**noreRoutes* – is this taken into account when







>>>> scanAllResources=false?







>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter

>> value







>>>> (cf. question ‘a’)?







>>>> b)      What would be the correct URL to generate a swagger.yaml

>>>> file



>>> for







>>>> each of the above interfaces? Initially I called:







>>>> *i.     **



>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*







>>>> *ii.    **



>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*







>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*







>>>> *lener/swagger.yaml*







>>>>    All three requests delivered the same yaml specification,



>>>> namely



>>> the one







>>>>       for interface* KmopApiServer*?







>>>> c)      I tried to debug the processing of the requests under ‘b)’

>>>> and



>>> this







>>>> is done by the class JAXRSInterceptor#processRequest where the







>>>> MessageImpl object for request “ii.” looks like the one attached.







>>>> It finds 3 resource







>>>> classes:







>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl







>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource







>>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService







>>>> è       It matches the request to resource*



>>> Swagger2ApiListingResource* with







>>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*







>>>> process(…)* method.







>>>> è       Here it seems to go wrong. It generates a

>> SwaggerContextService







>>>> having basePath=/op/services/resources/,swaggerConfig=null,







>>>> usePathBasedConfig=null and then calls







>>>> SwaggerContextService.getSwagger()







>>>> which returns the Swagger definition for interface KmopApiServer?







>>>> It looks like it caches generated swagger definitions based on a







>>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the







>>>> same for all 3 interfaces as usePathBasedConfig=null







>>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is







>>>> derived from the ServletConfig parameter







>>>> ‘swagger.use.path.based.config’.* So should this be set on the







>>>> declaration of the CXFServlet** in web.xml?*







>>>> è       Actually the SwaggerConfig, the JaxrsScanner and the

>>>> generated



>>> Swagger







>>>> are cached using keys like







>>>> ‘swagger.config.id.[default|baseUriPath]’, ‘







>>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’



>>> is only done when usePathBasedconfig=true.







>>>> è       If I patch this to true then configIdKey=’







>>>> swagger.config.id./op/services/resources/’ and no swagger entry is







>>>> cached for this key so it will generate a new one. Again by







>>>> patching







>>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru



>>>> e







>>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”







>>>> è       Again Scanners are cached and if usePathBasedConfig=null it



>>> will use







>>>> the one cached under  ‘swagger.scanner.id.default’ and this again







>>>> returns the swagger definition for the KmopApiService interface.







>>>> è       So patching usePathBasedConfig=true will return a new one







>>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner







>>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘







>>>> which is correct. It will generate a new (but empty) Swagger object.







>>>> è       Next Swagger2ApiListingResource will call the







>>>> customizer.customize(s), which still isn’t putting anything new in







>>>> the Swagger object. Should it or should the next step do this?







>>>> è       Next BaseApiListingResource#getListing(…) is called which on



>>> its







>>>> turn calls getListingYamlResponse(..)







>>>> è       The final result is a swagger.yaml document with following



>>> content:







>>>>    swagger: "2.0"







>>>>       info:







>>>>         license:







>>>>           name: "Apache 2.0 License"







>>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html







>>>>       basePath: "/op/services/resources"







>>>>        So basically an empty swagger file.







>>>> d)      The usePathBasedConfig is derived from the ServletConfig



>>> parameter ‘







>>>> swagger.use.path.based.config’. Without this parameter set to true







>>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger







>>>> object.* So should this be set on the declaration of the







>>>> CXFServlet** in web.xml?*







>>>> The majority in this processing happens in the library







>>>> swagger-jaxrs-v1.6.10 which is included as a dependency on



>>> cxf-rt-rs-service-description-swagger.







>>>> Even if I patch usePathBasedConfig=true about everywhere where I







>>>> met this it still doesn’t generate a correct swagger.yaml. Am I







>>>> still missing some configuration parameter?







>>>> Any suggestions on how to resolve this would be welcome.







>>>> Regards,







>>>> J.P. Urkens











































>>>> <<...>> <<...>>







>>>> -----Original Message-----







>>>> From: Andriy Redko <dr...@gmail.com>







>>>> Sent: maandag 8 mei 2023 23:15







>>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev







>>>> List <













>>>> Subject: Re: How to setup multiple JAXRS server endpoints







>>>> Hi Jean,







>>>> Indeed the way you would like to do that is somewhat tricky.







>>>>> So I tried to keep the @Path declaration on the interface classes



>>>>> but







>>>> changed them to @Path(“”). That does seems to work except the







>>>> swagger stuff no longer correctly works.







>>>> This is one of the possible options but OpenAPI/Swagger gets







>>>> confused for a







>>>> reason: the path is now implicit (not in the spec).







>>>> So how about this option:







>>>>  - use only one JAX-RS server (address "/")







>>>>  - host both resources but use @Path("accounts") and







>>>> @Path("resources") on them respectively











>>>> I see that for @Path("accounts") you need to apply the







>>>> "kmopApiAuthorizationFilter", that could be done using







>>>> DynamicFeature [1], [2]. If this is not the option and you would







>>>> prefer to use 2 separate JAX-RS servers, you may need to provide







>>>> your own instance of Swagger2Customizer [3], [4] which allows to







>>>> transform the OpenAPI/Swagger on the fly. Please let me know if



>>>> that



>>> would it work for you, thank you.







>>>> [1]







>>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic



>>>> F







>>>> eature.html







>>>> [2]







>>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born



>>>> -







>>>> equal.html







>>>> [3]







>>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger



>>>> /







>>>> Swagger2Customizer.html







>>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has







>>>> customizer







>>>> property)











>>>> Best Regards,







>>>>     Andriy Redko







>>>>> Hi Andriy,







>>>>> I am again getting into trouble with server endpoint declarations.







>>>>> Now







>>>> because I am adding additional JAX-RS endpoints.







>>>>> The issue is with:







>>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration

>>>>> in







>>>> combination with







>>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the

>>>>> web.xml







>>>> in combination with







>>>>> 3.      The @Path declaration in the interface class in combination

>>>>> with







>>>>> 4.      The @Path declaration on the interface method in

>>>>> combination

>> with







>>>>> So what I had is that my web application deployed under baseUlr 'op'







>>>>> had







>>>> one JAXRS server endpoint with declarations like:







>>>>> 1.      <jaxrs:server id="restServer"







>>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">







>>>>> 2.      <url-pattern>/services/*</url-pattern>







>>>>> 3.      @Path("accounts") on the public interface class







>>>>> 4.      @Path("/{authorisationId}/customerFund") on the

>>>>> customerFund







>>>> interface method







>>>>> A valid API call would thus be e.g.:







>>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/cu

>>>>> s



>>>>> t







>>>>> o







>>>>> merFund







>>>>> And this works correctly.







>>>>> We're now introducing additional JAX-RS service endpoints and now I







>>>>> am







>>>> running into problems. This second endpoint was declared with:







>>>>> 1.      <jaxrs:server id="resourceServer"







>>>> basePackages="be.dvtm.aeo.op.resources" address="/">







>>>>> 2.      <url-pattern>/services/*</url-pattern>







>>>>> 3.      @Path("resources") on the public interface class







>>>>> 4.      @Path("/NACE") on the NACE interface method







>>>>> So here a valid API call woud be:







>>>> https://<hostname>:<port>/op/services/resources/NACE.







>>>>> The problem is that I can not declare two <jaxrs:server> entries



>>>>> with







>>>>> the







>>>> same ‘address’ as it throws the exception:







>>>>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:







>>>> There is an endpoint already running on /.







>>>>>  So I tried changing the addresses to:







>>>>> ·       address=”accounts” for the restServer







>>>>> ·       address=”resources” for the resourceServer







>>>>> But to keep the API-call URLs the same I removed the @Path







>>>>> declaration on







>>>> the interface classes. By doing so the <jaxrs:server> bean







>>>> declarations no longer loads successfully.







>>>>> So I tried to keep the @Path declaration on the interface classes



>>>>> but







>>>> changed them to @Path(“”). That does seems to work except the







>>>> swagger stuff no longer correctly works.







>>>>> So what is the decent way to setup multiple JAX-RS server endpoints







>>>>> where







>>>> each server has its own configuration regarding supported features:







>>>>> ·       own validation







>>>>> ·       own object and exception mappings







>>>>> ·       own swagger file generation







>>>>> ·       own logging (in separate file if possible)







>>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in







>>>>> cooperation







>>>> with swager-ui v4.5.0.







>>>>> Below the declarations of my endpoints <<...>> Thanks for any advice.







>>>>> Regards,







>>>>> J.P. Urkens







>>>>> -----Original Message-----







>>>>> From: Andriy Redko <dr...@gmail.com>







>>>>> Sent: zaterdag 18 juni 2022 1:12







>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;







>>>>> issues@cxf.apache.org; dev@cxf.apache.org







>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,







>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'







>>>>> Correct, so in the relative form like address="/<something>", the







>>>>> JAX-RS







>>>> endpoint path would be:







>>>>>     <baseUrl>/<servlet path







mapping>>>>>>/<address>/[@ApplicationPath]/[@Path]







>>>>> The @ApplicationPath is optional in this case.







>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'







>>>>> The JAX-WS is very different from JAX-RS, essentially the action







>>>>> comes







>>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/







>>>> (@Path / @ApplicationPath are not relevant there).







>>>>>> Question: Because now address="/" is set for the jaxrs:server will







>>>>>> it







>>>>>> also inspect requests targeted for the jaxws service as those







>>>>>> requests have start with the same path '/<basePath>/services/...







>>>>> This is a good question, I have not done it myself but I think it







>>>>> should







>>>> work:







>>>>> the servlet dispatches according to registered services, in this







>>>>> regard







>>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?



>>> Thank you.







>>>>> Best Regards,







>>>>>     Andriy Redko







>>>>>> Hi Andriy,







>>>>>> Using address="/" seems to work but still I don't understand how



>>>>>> the







>>>>>> following work together:







>>>>>>  - path specification in servlet mapping for the CXF servlet







>>>>>> (org.apache.cxf.transport.servlet.CXFServlet)







>>>>>>  - the 'address' attribute on the jaxrs:server bean declaration







>>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the







>>>>>> service API description Say I've two services with (relateive to



>>>>>> the







>>>>>> host) url's:







>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'







>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'







>>>>>> How do I configure above 3 aspects? Currently I have (working):







>>>>>> 1.for the jaxrs:server endpoint:







>>>>>>         - servlet path mapping: '/services/*'







>>>>>>                - jaxrs-server address attribute: address="/"







>>>>>>                - @Path annotation: @Path("service1") 2.For the



>>>>>> jaxws







>>>>>> service endpoint:







>>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS







>>>>>> requests are handleb by the same CXF servle)







>>>>>>                - jaxws:endpoint server address attribute:







>>>>>> address="/service2"







>>>>>>                - @WebService(name="service2") A correct request

>>>>>> for







>>>>>> '1' would be '/basePath>/services/service1/<ID>'.







>>>>>> A correct request for '2' would be '/basePath>/services/service2'.







>>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:







>>>>>>         - the server address attribute







>>>>>>         - The API annotation (@Path or @Webservice) The JAXWS



>>>>>> server







>>>>>> address attribute doesn't seem to interfere with the @Webservice







>>>>>> annotation. While the jaxrs server address attribute does seem to







>>>>>> interfere with the @Path annotation. I would have expected the



>>>>>> jaxrs







>>>>>> server aspects to be configured as:







>>>>>>         - servlet path mapping: '/services/*'







>>>>>>                - jaxrs-server address attribute: address="/service1"







>>>>>>                - @Path annotation: @Path("service1") but then a







>>>>>> valid







>>>>>> request would be







>>>>>>> /services/service1/service1/<ID>'.







>>>>>> For both the 'address' attribute is relative to the servlet path.







>>>>>> The @Path Javadoc mentions that this path is relative to the







>>>>>> ApplicationPath which thus seems to be relative to the

>>>>>> jaxrs-server







>>>>>> address attribute. As for @Webservice it doesnn't seem to be







>>>>>> url-path







>>>> related.







>>>>>> Question: Because now address="/" is set for the jaxrs:server will







>>>>>> it







>>>>>> also inspect requests targeted for the jaxws service as those







>>>>>> requests have start with the same path '/<basePath>/services/...'.







>>>>>> Albeit somewhat confusing.







>>>>>> J.P.







>>>>>> -----Original Message-----







>>>>>> From: Andriy Redko <dr...@gmail.com>







>>>>>> Sent: dinsdag 14 juni 2022 1:08







>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;







>>>>>> issues@cxf.apache.org; dev@cxf.apache.org







>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi

>>>>>> Jean,







>>>>>> Indeed, the jaxrs:server does not expect address to be omitted,

>>>>>> you







>>>>>> could use the "/" (and I believe an empty string would also make it):







>>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...







>>>>>> </jaxrs:server>







>>>>>> Thank you.







>>>>>> Hope it helps.







>>>>>> Best Regards,







>>>>>>     Andriy Redko







>>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean







>>>>>>> declarations







>>>>>>> like:







>>>>>>>      <jaxrs:server id="restServer" basePackages="xxx">







>>>>>>>            <jaxrs:serviceBeans>







>>>>>>>                 <ref bean="TestApi" />







>>>>>>>            </jaxrs:serviceBeans>







>>>>>>>            <jaxrs:providers>







>>>>>>>                 <…/>







>>>>>>>            </jaxrs:providers>







>>>>>>>            <jaxrs:features>







>>>>>>>                 <… />







>>>>>>>            </jaxrs:features>







>>>>>>>            <jaxrs:inInterceptors>







>>>>>>>                 <… />







>>>>>>>            </jaxrs:inInterceptors>







>>>>>>>            <jaxrs:outInterceptors>*







>>>>>>>                 <**…**/>*







>>>>>>>            </jaxrs:outInterceptors>*







>>>>>>>      </jaxrs:server>











>>>>>>> Here my “TestApi” bean interface is declared like:







>>>>>>>       @Path("accounts")







>>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)







>>>>>>>        @Produces(MediaType.*APPLICATION_JSON*)







>>>>>>>        public interface TestApi {







>>>>>>>          …







>>>>>>>        }







>>>>>>> And CXF is triggered via a servlet configuration like:







>>>>>>>      <servlet>







>>>>>>>              <display-name>CXF Servlet</display-name>







>>>>>>>              <servlet-name>CXFServlet</servlet-name>







>>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servl

>>>>>>> e







>>>>>>> t













>>>>>>>        </servlet>







>>>>>>>        <servlet-mapping>







>>>>>>>              <servlet-name>CXFServlet</servlet-name>







>>>>>>>              <url-pattern>/services/*</url-pattern>







>>>>>>>        </servlet-mapping>











>>>>>>> Because I’ve got the @Path declaration on the interface type I’ve







>>>>>>> omitted







>>>>>>> the address=”accounts” attribute on the jaxrs:server declaration







>>>>>>> since otherwise







>>>>>>> I noticed that the server would be listening to







>>>>>>> /basepath/services/ accounts/accounts/…).







>>>>>>> Now this configuration works perfectly, only when shutting down







>>>>>>> the application server cxf calls







>>>>>>>         ServerImpl#destroy()







>>>>>>> which delegates (via Obeservable) to







>>>>>>> AbstractHTTPDestination#deactivate()







>>>>>>> which calls







>>>>>>> registry.removeDestination(path).







>>>>>>> This path is null (no ‘address’ specified on jaxrs:server







>>>>>>> declaration) and results in a NPE on the registry Map.







>>>>>>> This causes an unclean shutdown of my server.







>>>>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?







>>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration







>>>>>>> correctly interact with the @Path parameter on the API interface?







>>>> <<...>>


Re: Request mapping warnings

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
Could be, due to the (spring) @Service annotation in addition to the bean declaration in the cxf-endpoints.xml ?

Verzonden vanaf Outlook voor Android<https://aka.ms/AAb9ysg>
________________________________
From: Andrey Redko <dr...@gmail.com>
Sent: Wednesday, July 19, 2023 7:29:47 PM
To: Jean Pierre URKENS <je...@devoteam.com>
Cc: Daniel Kulp <de...@cxf.apache.org>
Subject: Re: Request mapping warnings

Hi Jean,

Indeed it looks like you have the same resource registered twice hence the warning. It may come from the use of automatic resource scans and manual resource registration.

Best Regards,
    Andriy Redko

On Wed, Jul 19, 2023, 7:39 AM Jean Pierre URKENS <je...@devoteam.com>> wrote:

Still some minor issue related to request mapping.

I notice I am getting warnings like:

2023-07-19 13:08:23,022 [T8N1TP1-4] WARN  (SID=8806F673DEC6B53D9248AF0DD81F6882) (org.apache.cxf.jaxrs.model.OperationResourceInfoComparatorBase:102) - Both be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#getDvlById and be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#getDvlById are equal candidates for handling the current request which can lead to unpredictable results

Obvious that they are equal candidates because they are the same class. But what is the cause of this double detection?

Is it because when JAXRSUtils.getRootResources(Message message)  gets called, I see that it contains 4 entries:

•       (twice) KmopDienstverlenerApiServiceImpl -> my service endpoint

•       io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

•       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService

So twice my service implementation, I wouldn’t know why this is the case?

On my classpath I have set:

•       cxf-rt-rs-service-description-3.5.6.jar                 -> this handles request for ‘_wadl’

•       cxf-rt-rs-service-description-openapi-v3-3.5.6.jar      -> this handles request for ‘openapi.[yaml|json]’

•       cxf-rt-rs-service-description-swagger-ui-3.5.6.jar      -> this handles request for ‘Swagger documentation’

would this be a cause for my service endpoint to appear multiple times? Aside from that I have no idea what could cause this.

J.P.

-----Original Message-----
From: Andriy Redko <dr...@gmail.com>>
Sent: donderdag 13 juli 2023 18:24
To: Jean Pierre URKENS <je...@devoteam.com>>; dev@cxf.apache.org<ma...@cxf.apache.org>
Subject: Re: How to setup multiple JAXRS server endpoints

Got it, thank you (the Swagger sometimes does surprising things).

Thursday, July 13, 2023, 1:33:07 AM, you wrote:

JPU> The @Parameter annotation seems to be ignored at this level.

JPU> -----Original Message-----

JPU> From: Jean Pierre URKENS <je...@devoteam.com>>

JPU> Sent: donderdag 13 juli 2023 7:11

JPU> To: 'Andriy Redko' <dr...@gmail.com>>; 'dev@cxf.apache.org<ma...@cxf.apache.org>'

JPU> <de...@cxf.apache.org>>

JPU> Subject: RE: How to setup multiple JAXRS server endpoints

JPU> Yes, SwaggerUI works too!

JPU> I noticed that v2.x of swagger-jaxrs relates to OpenApi v3.1.x

JPU> while my spec is compliant with OpenApi v3.0.x, so I am going to

JPU> stick with v2.1.13 which seems to be that last version for OpenApi v3.0.x.

JPU> I thought the @Parameter only applied to input parameters ("query",

JPU> "header", "path" or "cookie" parameters), but I'll give it a try.

JPU> J.P.

JPU> -----Original Message-----

JPU> From: Andriy Redko <dr...@gmail.com>>

JPU> Sent: woensdag 12 juli 2023 22:16

JPU> To: Jean Pierre URKENS <je...@devoteam.com>>;

JPU> dev@cxf.apache.org<ma...@cxf.apache.org>

JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

JPU> That's awesome, have you got SwaggerUI working as well?

JPU> Yes, you could use 2.2.15 (we already updated to this version, no

JPU> regressions). It seems like the description applies to the whole

JPU> schema (which is the same for both properties), may be you could

JPU> use @Parameter

JPU> instead:

JPU> @Parameter(description="The description I want for prop1")

JPU> Thank you.

JPU> Best Regards,

JPU>     Andriy Redko

>> Hi Andriy,

>> After having migrated everything to "io.swagger.v3.oas.annotations.*"

>> the swagger endpoints for each of my services became active.

>> So far so good, but I do notice that there are discrepancies when

>> annotating models, e.g.:

>>  public class Model1 {

>>   @Schema(description="The description I want for prop1")

>>    private Model2 prop1;

>>   @Schema(description="The description I want for prop2")

>>    private Model2 prop2;

>>   ...

>> }

>> When I generate the openapi.[json|yaml] specification I see that both

>> prop1 and prop2 have a reference to the schema component "Model2"

>> with description ' The description I want for prop2' which is

>> inappropriate for 'prop1'.

>> It is not unlikely to have multiple properties within one Model that

>> are of the same class but are semantically used in a different context. E.g.

>> something as simple as a ShipmentOrder having two 'Address'

>> properties 'from' and 'to' would result in wrong API documentation.

>> I am aware it has nothing to do with CXF but rather with

>> swagger-jaxrs2-vx.y.z.jar and depending libraries. CXF-3.5.6 has

>> dependency on swagger-jaxrs2-2.1.13.jar. Would it be an issue to

>> replace this dependency with e.g. swagger-jaxrs2-2.2.15.jar (latest

>> stable release according to maven central repo)?

>> J.P.

>> -----Original Message-----

>> From: Jean Pierre URKENS <je...@devoteam.com>>

>> Sent: woensdag 12 juli 2023 8:25

>> To: 'Andriy Redko' <dr...@gmail.com>>; 'dev@cxf.apache.org<ma...@cxf.apache.org>'

>> <de...@cxf.apache.org>>

>> Subject: RE: How to setup multiple JAXRS server endpoints I seem to

>> be mistaken here, the endpoint was loaded (I did a manual HTTP GET

>> test to the endpoint to verify this) although no breakpoints where

>> hit during startup.

>> I am first going to complete the migration to

>> "io.swagger.v3.oas.annotations.*" annotations for all endpoints and

>> then I am going to test again.

>> The application is composed of libraries, some of which use SLF4J but

>> most use LOG4J for logging.

>> J.P.

>> -----Original Message-----

>> From: Andriy Redko <dr...@gmail.com>>

>> Sent: woensdag 12 juli 2023 1:13

>> To: Jean Pierre URKENS <je...@devoteam.com>>;

>> dev@cxf.apache.org<ma...@cxf.apache.org>

>> Subject: Re: How to setup multiple JAXRS server endpoints Hi Jean,

>> The

>> OpenApiFeature$Portable#initiliaze(…) should definitely be called

>> (otherwise you shouldn't even see the openapi.json endpoint), so I am

>> not sure why these are not triggering for you.

>>

>> For logging, it seems like you are using SLF4J

>> (org.apache.cxf.common.logging.Slf4jLogger),

>> and also reload4j (aka log4j), why do you need both?

>> Thank you.

>> Best Regards,

>>     Andriy Redko

JPU>>> After some code investigation:


JPU>>> OpenApiFeature implements SwaggerUiSupport and in its

JPU>>> portable#registerSwaggerUiResources(…) method it will call

JPU>>> SwaggerUiSupport#getSwaggerUi(…) which will register the

JPU> SwaggerUiService.


JPU>>> I have put breakpoints on:

JPU>>>    - OpenApiFeature$Portable#initiliaze(…)

JPU>>>    - SwaggerUiService constructor

JPU>>>    - SwaggerUiSupport#getSwaggerUi(…)


JPU>>> but none of them are hit when starting my application?


JPU>>> Although the (spring) logging shows all beans in my

JPU>>> cxf-endpoints.xml have been created?

JPU>>> The *WADL* and *OpenAPI* endpoints to get the specification work.

JPU>>> Even the actual endpoint seems to work although I didn’t hit any

JPU>>> of the breakpoint?


JPU>>> CXF, also doesn’t seem to log a lot, I am hardly getting any log

JPU>>> entries although log level I set to DEBUG.

JPU>>> My logging (except wire message logging) for cxf is setup

JPU>>> correctly (I

JPU>>> think):

JPU>>>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line

JPU>>>    ‘org.apache.cxf.common.logging.Slf4jLogger’

JPU>>>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and

JPU>>>    reload4j-1.2.19.jar are on the classpath

JPU>>>    - the log4j.properties file contains the line:

JPU>>>    ‘log4j.logger.org.apache.cxf=DEBUG’


JPU>>> There are no special instructions mentioned on

JPU>>> https://cxf.apache.org/docs/general-cxf-logging.html<https://www.google.com/url?q=https://cxf.apache.org/docs/general-cxf-logging.html&source=gmail-imap&ust=1690392607000000&usg=AOvVaw0X-Atrg3WmGUN0dOcxyph_> so the above

JPU>>> should work (it works for all other packages I use in my application).


JPU>>> J.P.

JPU>>> *From:* Jean Pierre URKENS <je...@devoteam.com>>

JPU>>> *Sent:* dinsdag 11 juli 2023 9:58

JPU>>> *To:* 'Andriy Redko' <dr...@gmail.com>>; 'dev@cxf.apache.org<ma...@cxf.apache.org>' <

dev@cxf.apache.org<ma...@cxf.apache.org>>>>>

JPU>>> *Subject:* RE: How to setup multiple JAXRS server endpoints


JPU>>> Hi Andriy,


JPU>>> As a test I removed all JAX-RS endpoints that use Swagger v2

JPU>>> annotations from my configuration file (see attachment).

JPU>>> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger

JPU>>> v3 annotations, using the OpenApiFeature i.o. Swagger2Feature.

JPU>>> If I run my server with this configuration I only get the

JPU>>> (working)

JPU>>> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint:




JPU>>> So there is some configuration missing to detect/activate the

JPU>>> Swagger endpoint. When I look at the samples that come with the

JPU>>> distribution of CXF (I am using v3.5.6) nothing special seems to

JPU>>> be

JPU> configured to activate this?

JPU>>> Do you have any idea how the SwaggerUiService is picked up when

JPU> loading?


JPU>>> J.P.


JPU>>> -----Original Message-----

JPU>>> From: Andriy Redko <dr...@gmail.com>>

JPU>>> Sent: dinsdag 11 juli 2023 3:44

JPU>>> To: Jean Pierre URKENS <je...@devoteam.com>>;

JPU>>> dev@cxf.apache.org<ma...@cxf.apache.org>

JPU>>> Subject: Re: How to setup multiple JAXRS server endpoints


JPU>>> Hi Jean,


JPU>>> I guess you figured one issue, swagger.json -> openapi.json, but

JPU>>> to be honest we have never tested or envisioned the application

JPU>>> that would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same

JPU>>> time, I am afraid this is just not supported. You may get things

JPU>>> back on track when going with OpenAPI 3.0 for all services.


JPU>>> Thank you.


JPU>>> Best Regards,

JPU>>>     Andriy Redko




>>>> Hi Andriy,






>>>> I am trying to trace the difference in handling with another

>>>> application where I’ve got only one CXF service endpoint that uses

>>>> swagger v3 openapi annotations.


>>>> There I see that when handling the Swagger page request (

>>>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json<https://www.google.com/url?q=http://l-p53-008:8082/idb-fe/services/api-docs?url%3Dopenapi.json&source=gmail-imap&ust=1690392607000000&usg=AOvVaw1G2Og3QeJiV1LEwu0AqYSD>)

>>>> the JAXRSInInterceptor is calling:






>>>> *JAXRSUtils.**getRootResources*(Message message)






>>>> It contains 4 entries:


>>>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint

>>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

>>>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService














>>>> On the application described below with the service ‘oidcsim’ when

>>>> calling the swagger page request

>>>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the

>>>> result of the getRootResources doesn’t contain the

>>>> ClassResourceInfo ‘ SwaggerUiService’. It only contains 3 entries:


>>>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)

>>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource






>>>> The SwaggerUiService is the one that is configured to handle the

JPU>>> ‘api-docs’

>>>> path-request. Since it is missing the request is tried to match

>>>> with the other two resources but fails, hence ‘NOT FOUND’ exception.






>>>> I can’t trace back where these rootResources are set and why the

>>>> SwaggerUiService’ isn’t listed.






>>>> J.P.


>>>> *From:* Jean Pierre URKENS <je...@devoteam.com>>

>>>> *Sent:* maandag 10 juli 2023 13:43

>>>> *To:* 'Andriy Redko' <dr...@gmail.com>>

>>>> *Subject:* RE: How to setup multiple JAXRS server endpoints






>>>> Andriy,






>>>> I am trying to switch from Swagger v2 to OpenApi v3 annotations

>>>> basically because my starting point is an OpenApi v3.0.7 yaml file

>>>> description and OpenAPI seems to be the way forward.


>>>> For applications where I have only one CXF JAX-RS endpoint exposed

>>>> I had no problems converting. However as soon as there are multiple

>>>> endpoints I run into troubles.






>>>> So, to recall, I've an application exposing 3 JAX-RS endpoints that

>>>> where previously annotated with swagger v2 annotations (i.e.

>>>> package

>>>> io.swagger.annotations.*) which I migrated to


>>>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*).

>>>> In accordance I altered my CXF JAX-RS endpoint configuration from

>>>> (only showing relevant parts, see attachment for full setup):






>>>>                <!-- CXF Swagger2Feature -->


>>>>                <bean id="SwaggerUiConfigOidcApi"

>>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">


>>>>                               <property name="queryConfigEnabled"


>>>>                               <property name="url"

>>>> value="/op/services/oidcsim/swagger.yaml"/>


>>>>                </bean>


>>>>                <bean id="Swagger2FeatureOidcApi"

>>>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">


>>>>                               <property name="basePath"

>>>> value="/op/services/oidcsim"/>


>>>>                               <property name="usePathBasedConfig"


>>>>                               <property name="resourcePackage"

>>>> value="be.dvtm.aeo.op.oidc"/>


>>>>                               <property name="supportSwaggerUi"


>>>>                               <property name="swaggerUiConfig"

>>>> ref="SwaggerUiConfigOidcApi"/>


>>>>                </bean>


>>>>                <jaxrs:server id="OidcProviderApiServer"

>>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">


>>>>                               ....


>>>>                               <jaxrs:features>


>>>>                                              <ref

>>>> bean="Swagger2FeatureOidcApi" />


>>>>                               </jaxrs:features>


>>>>                               ...


>>>>                </jaxrs:server>






>>>> TO:


>>>>                <!-- CXF OpenAPIFeature -->


>>>>                <bean id="OidcSwaggerUiConfig"

>>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">


>>>>                               <property name="queryConfigEnabled"


>>>>                               <property name="url"

>>>> value="openapi.json"/>


>>>>                </bean>


>>>>                <bean id="OidcOpenApiFeature"

>>>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">


>>>>                               <property name="supportSwaggerUi"


>>>>                               <property name="swaggerUiConfig"

>>>> ref="OidcSwaggerUiConfig"/>


>>>>                               <property name="swaggerUiVersion"


>>>>                               <property name="scan" value="false"/>


>>>>                               <property name="useContextBasedConfig"


>>>>                               <property name="resourcePackages"

>>>> value="be.dvtm.aeo.op.oidc"/>


>>>>                </bean>


>>>>                <jaxrs:server id="OidcProviderApiServer"

>>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">


>>>>                               ....


>>>>                               <jaxrs:features>


>>>>                                              <ref

JPU>>> bean="OidcOpenApiFeature"


>>>>                               </jaxrs:features>


>>>>                               ...


>>>>                </jaxrs:server>










>>>> Now when starting my application and navigating to the root part "

>>>> http://localhost:localPort/op/services<https://www.google.com/url?q=http://localhost:localPort/op/services&source=gmail-imap&ust=1690392607000000&usg=AOvVaw0q1lbqVoJ4sKNpsGk3A2aO>" I get an overview of all my

>>>> endpoints:






>>>> Now there are 3 RESTful service endpoints setup:


>>>>    1. ‘oidcsim’ which I switched to swagger v3 annotations

>>>>    2. ‘openapi’ currently still swagger v2 annotations

>>>>    3. ‘sdx’ currently still swagger v2 annotations






>>>> all endpoints work except for the ‘swagger endpoint address for the

>>>> oidcsim

>>>> endpoint:

>>>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services<https://www.google.com/url?q=http://l-p53-008:8081/op/services/oidcsim/api-docs?url%3D/op/services&source=gmail-imap&ust=1690392607000000&usg=AOvVaw2cN_yBMrW61d06wXWcwyUV>

>>>> /o

>>>> i

>>>> dcsim/swagger.json


>>>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*

>>>> endpoint of the oidcsim resource. I am getting an error (the value

>>>> of the ‘url’ query parameter isn’t relevant):






>>>>         “WebApplicationException has been caught, status: 404,

>>>> message: HTTP 404 Not Found”






>>>> When I try (without the ‘/oidcsim’ context):

>>>> http://l-p53-008:8081/op/services/api-docs<https://www.google.com/url?q=http://l-p53-008:8081/op/services/api-docs&source=gmail-imap&ust=1690392607000000&usg=AOvVaw2LBUT21LD5iCPj6V9Os6Cc> I get:


>>>>                “No service was found.”






>>>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs<https://www.google.com/url?q=http://l-p53-008:8081/op/services/oidcsim/api-docs&source=gmail-imap&ust=1690392607000000&usg=AOvVaw3AH1wUOtj4rOEiNnzatPPi>

>>>> doesn’t exist, where as the endpoint

>>>> http://l-p53-008:8081/op/services/api-docs<https://www.google.com/url?q=http://l-p53-008:8081/op/services/api-docs&source=gmail-imap&ust=1690392607000000&usg=AOvVaw2LBUT21LD5iCPj6V9Os6Cc> does exist but no

>>>> service

JPU>>> description is found?


>>>> Of course my intention is to get working, as previously with the

>>>> swagger v2 setup for which I then specifically added the

>>>> *Swagger2Feature* config

>>>> parameters:


>>>>                               <property name="basePath"

>>>> value="/op/services/oidcsim"/>


>>>>                               <property name="usePathBasedConfig"






>>>> But I don’t find the according configuration options for the

>>>> *OpenApiFeature* class or whether I should configure this in

>>>> another way.






>>>> Any suggestions on this?






>>>> Regards,






>>>> J.P.










>>>> -----Original Message-----

>>>> From: Andriy Redko <dr...@gmail.com>>

>>>> Sent: donderdag 25 mei 2023 2:27

>>>> To: Jean Pierre URKENS <je...@devoteam.com>>;

>>>> dev@cxf.apache.org<ma...@cxf.apache.org>

>>>> Subject: Re: How to setup multiple JAXRS server endpoints






>>>> Hi Jean,






>>>> You may run into Swagger JAX-RS scanner limitations, as far as I

>>>> can tell - it checks class annotations for SwaggerDefinition, does

>>>> not traverse the hierarchy [1].






>>>> [1]

>>>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagge<https://www.google.com/url?q=https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagge&source=gmail-imap&ust=1690392607000000&usg=AOvVaw10u0c-7UKJlSdLCPL8Ngq_>

>>>> r-

>>>> j

>>>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194






>>>> Best Regards,


>>>>     Andriy Redko






>>>>>  RE: How to setup multiple JAXRS server endpoints






>>>>> Still one question );






>>>>> The generated swagger file doesn’t take into account the


>>>>> @SwaggerDefintion on my interface classes?






>>>>> As a test I looked at


>>>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m<https://www.google.com/url?q=https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m&source=gmail-imap&ust=1690392607000000&usg=AOvVaw3AJ56V_UasZ37CvYAf_Bp3>

>>>>> a


>>>>> in/release/samples/jax_rs/description_swagger2_web**


>>>>> and** modified** sample2*


>>>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m<https://www.google.com/url?q=https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m&source=gmail-imap&ust=1690392607000000&usg=AOvVaw3AJ56V_UasZ37CvYAf_Bp3>

>>>>> a


>>>>> in/release/samples/jax_rs/description_swagger2_web


>>>>> and modified sample2> as follows:






>>>>>    @Path("/sample2")






>>>>>       @Api(value = "/sample2",authorizations=


>>>>>       {@Authorization(value="bearer")},description = "Sample2

>>>> (modified) JAX-RS


>>>>>       service with Swagger documentation")






>>>>>       @SwaggerDefinition(






>>>>>               info = @Info(






>>>>>                       description = "Sample2 server",






>>>>>                       version="1.0",






>>>>>                       title = "Test2",






>>>>>                       contact = @Contact(name = "J.P. Urkens",email = "


>>>>>       *jean-pierre.urkens@devoteam.com*<mailto:*jean-pierre.urkens@devoteam.com*> <

>>>> jean-pierre.urkens@devoteam.com<ma...@devoteam.com>>


>>>>>       ")),






>>>>>               securityDefinition =


>>>>>       @SecurityDefinition(apiKeyAuthDefinitions=


>>>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name=<mailto:*%7B@ApiKeyAuthDefinition(key=>

>>>> "A

>>>> u

>>>> thorization",description="Use*


>>>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer


>>>>>       &lt;accessToken&gt;'")})






>>>>>       )






>>>>>       public class Sample2 {...}






>>>>> This correctly generates the ‘securityDefintions’ in the swagger file.






>>>>> If include the same @SwaggerDefinition and the authorizations on


>>>>> the @Api annotation as above in my interface classes then the


>>>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?






>>>>> Any idea what I might be missing?






>>>>> Regards,






>>>>> J.P.






>>>>> -----Original Message-----


>>>>> From: Jean Pierre URKENS <je...@devoteam.com>>


>>>>> Sent: dinsdag 23 mei 2023 12:52


>>>>> To: 'Andriy Redko' <dr...@gmail.com>>; 'dev@cxf.apache.org<ma...@cxf.apache.org>' <




>>>>> Subject: RE: How to setup multiple JAXRS server endpoints






>>>>> Hi Andriy,






>>>>> I added the parameter usePathBasedConfig=true to the


>>>>> Swagger2Feature bean declarations but still it does generate an


>>>>> empty swagger.yaml for interfaces KmopResources and


>>>>> KmopDienstverlener although I noticed that for these interfaces

>>>>> the


>>>>> @Path() annotation was commented out (as I included it in the


>>>>> server declaration). After providing an empty @Path("")

>>>>> declaration on

>>>> the API interface classes everything worked.






>>>>> Thanks for the support.






>>>>> -----Original Message-----






>>>>> From: Andriy Redko <dr...@gmail.com>>






>>>>> Sent: dinsdag 23 mei 2023 3:42






>>>>> To: Jean Pierre URKENS <je...@devoteam.com>>;


>>>>> dev@cxf.apache.org<ma...@cxf.apache.org>






>>>>> Subject: Re: How to setup multiple JAXRS server endpoints






>>>>> Hi Jean,






>>>>> The main problem to configure Swagger property in your particular


>>>>> case is that the server address is not "known" or "introspectable"

>>>>> for

>>>> Swagger.


>>>>> Intuitively, it has to be set manually using basePath to the,


>>>>> essentially, the server address






>>>>> part:






>>>>>  - /op/services/accounts






>>>>>  - /op/services/resources






>>>>>  - /op/services/dienstverlener






>>>>> You could read more about other Swagger properties you have asked here:


>>>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Int<https://www.google.com/url?q=https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Int&source=gmail-imap&ust=1690392607000000&usg=AOvVaw0zHkbffhLxrrSPHNHJnTHQ>

>>>>> e


>>>>> gration-and-Configuration#configuration-properties






>>>>> You definitely need to set usePathBasedConfig to "true" otherwise


>>>>> you will see the same Swagger specs for all servers. We have a


>>>>> sample here which uses 2 jaxrs:server






>>>>> instances:


>>>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma<https://www.google.com/url?q=https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma&source=gmail-imap&ust=1690392607000000&usg=AOvVaw3MRzc_HMpnuaQ4d6yr9dNd>

>>>>> i


>>>>> n/release/samples/jax_rs/description_swagger2_web






>>>>> Regarding SwaggerUI, I think the value for each of those should be


>>>>> set to,


>>>>> respectively:






>>>>>  - /op/services/accounts/swagger.yaml






>>>>>  - /op/services/resources/swagger.yaml






>>>>>  - /op/services/dienstverlener/swagger.yaml






>>>>> I believe this is matching your settings already, except the


>>>>> usePathBasedConfig part. The example referred above could be


>>>>> helpful, my apologies if I missed something, there are quite a lot


>>>>> of questions :-) The fact that the generated Swagger specification


>>>>> is empty is unexpected - it should not happen when JAX-RS

>>>>> resources

>>>> are properly configured.






>>>>> Thank you.






>>>>> Best Regards,






>>>>>     Andriy Redko






>>>>>>  RE: How to setup multiple JAXRS server endpoints






>>>>>> Hi Andriy,






>>>>>> I am not quite understanding how to correctly configure the


>>>>> Swagger2Feature.






>>>>>> Referring to the attached cxf-endpoints configuration I (as a


>>>>>> test)






>>>>>> created






>>>>>> 3 JAXRS server instances:






>>>>>> 1.      A* KmopApiServer* server for the*






>>>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving






>>>>>> requests for URI path:






>>>>>>        * <protocol>**//<host:<port>/op/services/accounts*






>>>>>>    ‘op’  = root path of the web application






>>>>>>             ‘services’ = servlet path of the CXF-servlet






>>>>>>       The address of the server is set to ‘/accounts’ and the


>>>>>> @Path(…)






>>>>>>       annotation on the interface class was cleared.






>>>>>> 2.      A* Kmop**Resources**ApiServer* server for the*

>>>> be.dvtm.aeo.op.*






>>>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving






>>>>>> requests for URI path:






>>>>>>        * <protocol>**//<host:<port>/op/services/**resources*






>>>>>> The address of the server is set to ‘/resources’ and the @Path(…)






>>>>>> annotation on the interface class was cleared.






>>>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*


>>>>> be.dvtm.aeo.op.*






>>>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving






>>>>>> requests for URI path:






>>>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*






>>>>>> The address of the server is set to ‘/dienstverlener’ and the






>>>>>> @Path(…) annotation on the interface class was cleared.






>>>>>> For each of these server instances I’ve set the Swagger2Feature






>>>>>> with configuration as indicated in the attached cxf-endpoints.xml.






>>>>>> With regard to the configurations for the Swagger2Feature I’ve

>>>>>> the






>>>>>> following questions:






>>>>>> a)      Referring to *

>>>> https://cxf.apache.org/docs/swagger2feature.html*<https://www.google.com/url?q=https://cxf.apache.org/docs/swagger2feature.html*&source=gmail-imap&ust=1690392607000000&usg=AOvVaw31hDfdm_eEFywFpE_hOdp_>






>>>>>> <https://cxf.apache.org/docs/swagger2feature.html<https://www.google.com/url?q=https://cxf.apache.org/docs/swagger2feature.html&source=gmail-imap&ust=1690392607000000&usg=AOvVaw0GpGaZWr4kIHAIjYgMpouX>>  could you






>>>>>> clarify on the following configuration parameters:






>>>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘






>>>>>> /op/services’) or to the JAX-RS server instance (e.g.






>>>>>> ‘/op/services/accounts’) or still something else? Is it used to






>>>>>> resolve service classes or is it just for documentation in the


>>>>>> swagger


>>>>> file?






>>>>>> *ii.    ** resourcePackage* – the description mentions ‘package names’






>>>>>> while the default mentions ‘service classes’? Service 2 and 3


>>>>>> above






>>>>>> are within the same package (generated from the same yaml






>>>>>> specification that included both interfaces).






>>>>>> *iii.   ** ig**noreRoutes* – is this taken into account when






>>>>>> scanAllResources=false?






>>>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter

>>>> value






>>>>>> (cf. question ‘a’)?






>>>>>> b)      What would be the correct URL to generate a swagger.yaml

>>>>>> file


>>>>> for






>>>>>> each of the above interfaces? Initially I called:






>>>>>> *i.     **


>>>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*






>>>>>> *ii.    **


>>>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*






>>>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*






>>>>>> *lener/swagger.yaml*






>>>>>>    All three requests delivered the same yaml specification,


>>>>>> namely


>>>>> the one






>>>>>>       for interface* KmopApiServer*?






>>>>>> c)      I tried to debug the processing of the requests under ‘b)’

>>>>>> and


>>>>> this






>>>>>> is done by the class JAXRSInterceptor#processRequest where the






>>>>>> MessageImpl object for request “ii.” looks like the one attached.






>>>>>> It finds 3 resource






>>>>>> classes:






>>>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl






>>>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource






>>>>>>       org.apache

RE: Request mapping warnings

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
Hi Andriy,

Removing the basepackages property indeed resolved the issue.

Regards,

J.P. Urkens

-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: dinsdag 25 juli 2023 2:32
To: Jean Pierre URKENS <je...@devoteam.com>
Cc: Daniel Kulp <de...@cxf.apache.org>
Subject: Re: Request mapping warnings

Hi Jean,

The issue with duplicate beans registration comes from JAXRS server
definition:

        <jaxrs:server id="KmopOpenApiServer"
basePackages="be.dvtm.aeo.op.openapi" address="/openapi">

The basePackages property triggers automatic scans which basically means
that the same beans will be discovered twice. I think you could safely bring
the @Service annotation back and remove basePackages property to get rid of
the issue.

Thanks!

Best Regards,
    Andriy Redko

JPU> No, I am not using SpringBoot in any way.



JPU> Regards,



JPU> J.P.



JPU> *From:* Andrey Redko <dr...@gmail.com>
JPU> *Sent:* donderdag 20 juli 2023 15:24
JPU> *To:* Jean Pierre URKENS <je...@devoteam.com>
JPU> *Cc:* Daniel Kulp <de...@cxf.apache.org>
JPU> *Subject:* Re: Request mapping warnings



JPU> Hi Jean,



JPU> Do you use CXF Spring Boot autoconfiguration [1]? If yes, it has a
JPU> few controls over scans [1], either beans or classes (I am off this
JPU> week so cannot look into the configuration). Thank you.


JPU> [1] https://cxf.apache.org/docs/springboot.html

JPU> Best Regards,
JPU>     Andriy Redko



JPU> On Thu, Jul 20, 2023, 2:23 AM Jean Pierre URKENS <
JPU> jean-pierre.urkens@devoteam.com> wrote:

JPU> Hi all,



JPU> As a test I removed the @org.springframework.stereotype.Service(“
JPU> *KmopDienstverlenerApi*”) annotation on my service implementation
JPU> class. So no @Service annotations further exist. Still when
JPU> checking the return of *JAXRSUtils.**getRootResources*(Message
JPU> message) via breakpoint I

JPU> Still notice that my service classes are listed twice in the return
JPU> result *List<ClassResourceInfo>*.



JPU> The only annotations I’ve left in my code are:

JPU>    - standard JAX-RS annotations:
JPU>
javax.ws.rs.[GET|POST|Consumes|Produces|HeaderParam|PathParam|QueryParam|Path|core.MediaType|core.Response]
JPU>    - io.swagger.v3.oas.annotations.*

JPU> I suppose none of these would be responsible for an extra
JPU> registration of my service classes.



JPU> So the only point where service registration occurs is in the bean
JPU> declaration file cxf-endpoint.xml, see attachment. The only thing I
JPU> can think of a possible double registration in this file is the
JPU> declaration of the OpenApiFeature (e.g. <bean
JPU> id=”*KmopOpenApiFeature*” …> ) for each resource endpoint in
JPU> addition to the <jaxrs:server /> declaration using this OpenApiFeature.

JPU> But I would assume that configuring the OpenApiFeature, through a
JPU> bean declaration, wouldn’t register a service.



JPU> The ‘imported’ resources context-v2.xml and onderneming-context.xml
JPU> define some <jaxws:client/> instances that have nothing to do with
JPU> these JAX-WS/RS endpoints declared in this file.



JPU> Is there something I can trace into to see when a service gets
JPU> registered as a *ClassResourceInfo *?



JPU> Regards,



JPU> J.P. Urkens

JPU> *From:* Andrey Redko <dr...@gmail.com>
JPU> *Sent:* woensdag 19 juli 2023 19:30
JPU> *To:* Jean Pierre URKENS <je...@devoteam.com>
JPU> *Cc:* Daniel Kulp <de...@cxf.apache.org>
JPU> *Subject:* Re: Request mapping warnings



JPU> Hi Jean,



JPU> Indeed it looks like you have the same resource registered twice
JPU> hence the warning. It may come from the use of automatic resource
JPU> scans and manual resource registration.

JPU> Best Regards,
JPU>     Andriy Redko



JPU> On Wed, Jul 19, 2023, 7:39 AM Jean Pierre URKENS <
JPU> jean-pierre.urkens@devoteam.com> wrote:

JPU> Still some minor issue related to request mapping.

JPU> I notice I am getting warnings like:

JPU> *2023-07-19 13:08:23,022 [T8N1TP1-4] WARN
JPU> (SID=8806F673DEC6B53D9248AF0DD81F6882)
JPU> (org.apache.cxf.jaxrs.model.OperationResourceInfoComparatorBase:102
JPU> ) - Both
JPU> be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#ge
JPU> tDvlById
JPU> and
JPU> be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#ge
JPU> tDvlById are equal candidates for handling the current request
JPU> which can lead to unpredictable results*

JPU> Obvious that they are equal candidates because they are the same
JPU> class. But what is the cause of this double detection?

JPU> Is it because when *JAXRSUtils.**getRootResources*(Message message)
JPU> gets called, I see that it contains 4 entries:

JPU> ·       (twice) KmopDienstverlenerApiServiceImpl -> my service endpoint

JPU> ·       io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

JPU> ·       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService

JPU> So twice my service implementation, I wouldn’t know why this is the
case?

JPU> On my classpath I have set:

JPU> ·       cxf-rt-rs-service-description-3.5.6.jar                 -> this
JPU> handles request for ‘_wadl’

JPU> ·       cxf-rt-rs-service-description-openapi-v3-3.5.6.jar      -> this
JPU> handles request for ‘openapi.[yaml|json]’

JPU> ·       cxf-rt-rs-service-description-swagger-ui-3.5.6.jar      -> this
JPU> handles request for ‘Swagger documentation’

JPU> would this be a cause for my service endpoint to appear multiple times?
JPU> Aside from that I have no idea what could cause this.

JPU> J.P.

JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: donderdag 13 juli 2023 18:24
JPU> To: Jean Pierre URKENS <je...@devoteam.com>;
JPU> dev@cxf.apache.org
JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Got it, thank you (the Swagger sometimes does surprising things).

JPU> Thursday, July 13, 2023, 1:33:07 AM, you wrote:

JPU>> The @Parameter annotation seems to be ignored at this level.

JPU>> -----Original Message-----

JPU>> From: Jean Pierre URKENS <je...@devoteam.com>

JPU>> Sent: donderdag 13 juli 2023 7:11

JPU>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'

JPU>> <de...@cxf.apache.org>

JPU>> Subject: RE: How to setup multiple JAXRS server endpoints

JPU>> Yes, SwaggerUI works too!

JPU>> I noticed that v2.x of swagger-jaxrs relates to OpenApi v3.1.x

JPU>> while my spec is compliant with OpenApi v3.0.x, so I am going to

JPU>> stick with v2.1.13 which seems to be that last version for OpenApi
JPU> v3.0.x.

JPU>> I thought the @Parameter only applied to input parameters
JPU>> ("query",

JPU>> "header", "path" or "cookie" parameters), but I'll give it a try.

JPU>> J.P.

JPU>> -----Original Message-----

JPU>> From: Andriy Redko <dr...@gmail.com>

JPU>> Sent: woensdag 12 juli 2023 22:16

JPU>> To: Jean Pierre URKENS <je...@devoteam.com>;

JPU>> dev@cxf.apache.org

JPU>> Subject: Re: How to setup multiple JAXRS server endpoints

JPU>> Hi Jean,

JPU>> That's awesome, have you got SwaggerUI working as well?

JPU>> Yes, you could use 2.2.15 (we already updated to this version, no

JPU>> regressions). It seems like the description applies to the whole

JPU>> schema (which is the same for both properties), may be you could

JPU>> use @Parameter

JPU>> instead:

JPU>> @Parameter(description="The description I want for prop1")

JPU>> Thank you.

JPU>> Best Regards,

JPU>>     Andriy Redko

>>> Hi Andriy,

>>> After having migrated everything to "io.swagger.v3.oas.annotations.*"

>>> the swagger endpoints for each of my services became active.

>>> So far so good, but I do notice that there are discrepancies when

>>> annotating models, e.g.:

>>>  public class Model1 {

>>>   @Schema(description="The description I want for prop1")

>>>    private Model2 prop1;

>>>   @Schema(description="The description I want for prop2")

>>>    private Model2 prop2;

>>>   ...

>>> }

>>> When I generate the openapi.[json|yaml] specification I see that
>>> both

>>> prop1 and prop2 have a reference to the schema component "Model2"

>>> with description ' The description I want for prop2' which is

>>> inappropriate for 'prop1'.

>>> It is not unlikely to have multiple properties within one Model that

>>> are of the same class but are semantically used in a different context.
JPU> E.g.

>>> something as simple as a ShipmentOrder having two 'Address'

>>> properties 'from' and 'to' would result in wrong API documentation.

>>> I am aware it has nothing to do with CXF but rather with

>>> swagger-jaxrs2-vx.y.z.jar and depending libraries. CXF-3.5.6 has

>>> dependency on swagger-jaxrs2-2.1.13.jar. Would it be an issue to

>>> replace this dependency with e.g. swagger-jaxrs2-2.2.15.jar (latest

>>> stable release according to maven central repo)?

>>> J.P.

>>> -----Original Message-----

>>> From: Jean Pierre URKENS <je...@devoteam.com>

>>> Sent: woensdag 12 juli 2023 8:25

>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'

>>> <de...@cxf.apache.org>

>>> Subject: RE: How to setup multiple JAXRS server endpoints I seem to

>>> be mistaken here, the endpoint was loaded (I did a manual HTTP GET

>>> test to the endpoint to verify this) although no breakpoints where

>>> hit during startup.

>>> I am first going to complete the migration to

>>> "io.swagger.v3.oas.annotations.*" annotations for all endpoints and

>>> then I am going to test again.

>>> The application is composed of libraries, some of which use SLF4J
>>> but

>>> most use LOG4J for logging.

>>> J.P.

>>> -----Original Message-----

>>> From: Andriy Redko <dr...@gmail.com>

>>> Sent: woensdag 12 juli 2023 1:13

>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>> dev@cxf.apache.org

>>> Subject: Re: How to setup multiple JAXRS server endpoints Hi Jean,

>>> The

>>> OpenApiFeature$Portable#initiliaze(…) should definitely be called

>>> (otherwise you shouldn't even see the openapi.json endpoint), so I
>>> am

>>> not sure why these are not triggering for you.

>>>

>>> For logging, it seems like you are using SLF4J

>>> (org.apache.cxf.common.logging.Slf4jLogger),

>>> and also reload4j (aka log4j), why do you need both?

>>> Thank you.

>>> Best Regards,

>>>     Andriy Redko

JPU>>>> After some code investigation:



JPU>>>> OpenApiFeature implements SwaggerUiSupport and in its

JPU>>>> portable#registerSwaggerUiResources(…) method it will call

JPU>>>> SwaggerUiSupport#getSwaggerUi(…) which will register the

JPU>> SwaggerUiService.



JPU>>>> I have put breakpoints on:

JPU>>>>    - OpenApiFeature$Portable#initiliaze(…)

JPU>>>>    - SwaggerUiService constructor

JPU>>>>    - SwaggerUiSupport#getSwaggerUi(…)



JPU>>>> but none of them are hit when starting my application?



JPU>>>> Although the (spring) logging shows all beans in my

JPU>>>> cxf-endpoints.xml have been created?

JPU>>>> The *WADL* and *OpenAPI* endpoints to get the specification work.

JPU>>>> Even the actual endpoint seems to work although I didn’t hit any

JPU>>>> of the breakpoint?



JPU>>>> CXF, also doesn’t seem to log a lot, I am hardly getting any log

JPU>>>> entries although log level I set to DEBUG.

JPU>>>> My logging (except wire message logging) for cxf is setup

JPU>>>> correctly (I

JPU>>>> think):

JPU>>>>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line

JPU>>>>    ‘org.apache.cxf.common.logging.Slf4jLogger’

JPU>>>>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and

JPU>>>>    reload4j-1.2.19.jar are on the classpath

JPU>>>>    - the log4j.properties file contains the line:

JPU>>>>    ‘log4j.logger.org.apache.cxf=DEBUG’



JPU>>>> There are no special instructions mentioned on

JPU>>>> https://cxf.apache.org/docs/general-cxf-logging.html so the
JPU>>>> above

JPU>>>> should work (it works for all other packages I use in my
JPU> application).



JPU>>>> J.P.

JPU>>>> *From:* Jean Pierre URKENS <je...@devoteam.com>

JPU>>>> *Sent:* dinsdag 11 juli 2023 9:58

JPU>>>> *To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <

dev@cxf.apache.org>>>>>

JPU>>>> *Subject:* RE: How to setup multiple JAXRS server endpoints



JPU>>>> Hi Andriy,



JPU>>>> As a test I removed all JAX-RS endpoints that use Swagger v2

JPU>>>> annotations from my configuration file (see attachment).

JPU>>>> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger

JPU>>>> v3 annotations, using the OpenApiFeature i.o. Swagger2Feature.

JPU>>>> If I run my server with this configuration I only get the

JPU>>>> (working)

JPU>>>> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint:



JPU>>>> So there is some configuration missing to detect/activate the

JPU>>>> Swagger endpoint. When I look at the samples that come with the

JPU>>>> distribution of CXF (I am using v3.5.6) nothing special seems to

JPU>>>> be

JPU>> configured to activate this?

JPU>>>> Do you have any idea how the SwaggerUiService is picked up when

JPU>> loading?



JPU>>>> J.P.



JPU>>>> -----Original Message-----

JPU>>>> From: Andriy Redko <dr...@gmail.com>

JPU>>>> Sent: dinsdag 11 juli 2023 3:44

JPU>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

JPU>>>> dev@cxf.apache.org

JPU>>>> Subject: Re: How to setup multiple JAXRS server endpoints



JPU>>>> Hi Jean,



JPU>>>> I guess you figured one issue, swagger.json -> openapi.json, but

JPU>>>> to be honest we have never tested or envisioned the application

JPU>>>> that would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same

JPU>>>> time, I am afraid this is just not supported. You may get things

JPU>>>> back on track when going with OpenAPI 3.0 for all services.



JPU>>>> Thank you.



JPU>>>> Best Regards,

JPU>>>>     Andriy Redko



>>>>> Hi Andriy,




>>>>> I am trying to trace the difference in handling with another

>>>>> application where I’ve got only one CXF service endpoint that uses

>>>>> swagger v3 openapi annotations.



>>>>> There I see that when handling the Swagger page request (

>>>>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json)

>>>>> the JAXRSInInterceptor is calling:




>>>>> *JAXRSUtils.**getRootResources*(Message message)




>>>>> It contains 4 entries:



>>>>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint

>>>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

>>>>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService












>>>>> On the application described below with the service ‘oidcsim’ when

>>>>> calling the swagger page request

>>>>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the

>>>>> result of the getRootResources doesn’t contain the

>>>>> ClassResourceInfo ‘ SwaggerUiService’. It only contains 3 entries:



>>>>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)

>>>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource




>>>>> The SwaggerUiService is the one that is configured to handle the

JPU>>>> ‘api-docs’

>>>>> path-request. Since it is missing the request is tried to match

>>>>> with the other two resources but fails, hence ‘NOT FOUND’ exception.




>>>>> I can’t trace back where these rootResources are set and why the

>>>>> SwaggerUiService’ isn’t listed.




>>>>> J.P.



>>>>> *From:* Jean Pierre URKENS <je...@devoteam.com>

>>>>> *Sent:* maandag 10 juli 2023 13:43

>>>>> *To:* 'Andriy Redko' <dr...@gmail.com>

>>>>> *Subject:* RE: How to setup multiple JAXRS server endpoints




>>>>> Andriy,




>>>>> I am trying to switch from Swagger v2 to OpenApi v3 annotations

>>>>> basically because my starting point is an OpenApi v3.0.7 yaml file

>>>>> description and OpenAPI seems to be the way forward.



>>>>> For applications where I have only one CXF JAX-RS endpoint exposed

>>>>> I had no problems converting. However as soon as there are
>>>>> multiple

>>>>> endpoints I run into troubles.




>>>>> So, to recall, I've an application exposing 3 JAX-RS endpoints
>>>>> that

>>>>> where previously annotated with swagger v2 annotations (i.e.

>>>>> package

>>>>> io.swagger.annotations.*) which I migrated to



>>>>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*).

>>>>> In accordance I altered my CXF JAX-RS endpoint configuration from

>>>>> (only showing relevant parts, see attachment for full setup):




>>>>>                <!-- CXF Swagger2Feature -->



>>>>>                <bean id="SwaggerUiConfigOidcApi"

>>>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>>>>>                               <property name="queryConfigEnabled"



>>>>>                               <property name="url"

>>>>> value="/op/services/oidcsim/swagger.yaml"/>



>>>>>                </bean>



>>>>>                <bean id="Swagger2FeatureOidcApi"

>>>>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">



>>>>>                               <property name="basePath"

>>>>> value="/op/services/oidcsim"/>



>>>>>                               <property name="usePathBasedConfig"



>>>>>                               <property name="resourcePackage"

>>>>> value="be.dvtm.aeo.op.oidc"/>



>>>>>                               <property name="supportSwaggerUi"



>>>>>                               <property name="swaggerUiConfig"

>>>>> ref="SwaggerUiConfigOidcApi"/>



>>>>>                </bean>



>>>>>                <jaxrs:server id="OidcProviderApiServer"

>>>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>>>>>                               ....



>>>>>                               <jaxrs:features>



>>>>>                                              <ref

>>>>> bean="Swagger2FeatureOidcApi" />



>>>>>                               </jaxrs:features>



>>>>>                               ...



>>>>>                </jaxrs:server>




>>>>> TO:



>>>>>                <!-- CXF OpenAPIFeature -->



>>>>>                <bean id="OidcSwaggerUiConfig"

>>>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>>>>>                               <property name="queryConfigEnabled"



>>>>>                               <property name="url"

>>>>> value="openapi.json"/>



>>>>>                </bean>



>>>>>                <bean id="OidcOpenApiFeature"

>>>>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">



>>>>>                               <property name="supportSwaggerUi"



>>>>>                               <property name="swaggerUiConfig"

>>>>> ref="OidcSwaggerUiConfig"/>



>>>>>                               <property name="swaggerUiVersion"



>>>>>                               <property name="scan"
>>>>> value="false"/>



>>>>>                               <property name="useContextBasedConfig"



>>>>>                               <property name="resourcePackages"

>>>>> value="be.dvtm.aeo.op.oidc"/>



>>>>>                </bean>



>>>>>                <jaxrs:server id="OidcProviderApiServer"

>>>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>>>>>                               ....



>>>>>                               <jaxrs:features>



>>>>>                                              <ref

JPU>>>> bean="OidcOpenApiFeature"



>>>>>                               </jaxrs:features>



>>>>>                               ...



>>>>>                </jaxrs:server>








>>>>> Now when starting my application and navigating to the root part "

>>>>> http://localhost:localPort/op/services" I get an overview of all
>>>>> my

>>>>> endpoints:




>>>>> Now there are 3 RESTful service endpoints setup:



>>>>>    1. ‘oidcsim’ which I switched to swagger v3 annotations

>>>>>    2. ‘openapi’ currently still swagger v2 annotations

>>>>>    3. ‘sdx’ currently still swagger v2 annotations




>>>>> all endpoints work except for the ‘swagger endpoint address for
>>>>> the

>>>>> oidcsim

>>>>> endpoint:

>>>>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/service
>>>>> s

>>>>> /o

>>>>> i

>>>>> dcsim/swagger.json



>>>>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*

>>>>> endpoint of the oidcsim resource. I am getting an error (the value

>>>>> of the ‘url’ query parameter isn’t relevant):




>>>>>         “WebApplicationException has been caught, status: 404,

>>>>> message: HTTP 404 Not Found”




>>>>> When I try (without the ‘/oidcsim’ context):

>>>>> http://l-p53-008:8081/op/services/api-docs I get:



>>>>>                “No service was found.”




>>>>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs

>>>>> doesn’t exist, where as the endpoint

>>>>> http://l-p53-008:8081/op/services/api-docs does exist but no

>>>>> service

JPU>>>> description is found?



>>>>> Of course my intention is to get working, as previously with the

>>>>> swagger v2 setup for which I then specifically added the

>>>>> *Swagger2Feature* config

>>>>> parameters:



>>>>>                               <property name="basePath"

>>>>> value="/op/services/oidcsim"/>



>>>>>                               <property name="usePathBasedConfig"




>>>>> But I don’t find the according configuration options for the

>>>>> *OpenApiFeature* class or whether I should configure this in

>>>>> another way.




>>>>> Any suggestions on this?




>>>>> Regards,




>>>>> J.P.








>>>>> -----Original Message-----

>>>>> From: Andriy Redko <dr...@gmail.com>

>>>>> Sent: donderdag 25 mei 2023 2:27

>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>>>> dev@cxf.apache.org

>>>>> Subject: Re: How to setup multiple JAXRS server endpoints




>>>>> Hi Jean,




>>>>> You may run into Swagger JAX-RS scanner limitations, as far as I

>>>>> can tell - it checks class annotations for SwaggerDefinition, does

>>>>> not traverse the hierarchy [1].




>>>>> [1]

>>>>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagg
>>>>> e

>>>>> r-

>>>>> j

>>>>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194




>>>>> Best Regards,



>>>>>     Andriy Redko




>>>>>>  RE: How to setup multiple JAXRS server endpoints




>>>>>> Still one question );




>>>>>> The generated swagger file doesn’t take into account the



>>>>>> @SwaggerDefintion on my interface classes?




>>>>>> As a test I looked at



>>>>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/
>>>>>> m

>>>>>> a



>>>>>> in/release/samples/jax_rs/description_swagger2_web**



>>>>>> and** modified** sample2*



>>>>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/
>>>>>> m

>>>>>> a



>>>>>> in/release/samples/jax_rs/description_swagger2_web



>>>>>> and modified sample2> as follows:




>>>>>>    @Path("/sample2")




>>>>>>       @Api(value = "/sample2",authorizations=



>>>>>>       {@Authorization(value="bearer")},description = "Sample2

>>>>> (modified) JAX-RS



>>>>>>       service with Swagger documentation")




>>>>>>       @SwaggerDefinition(




>>>>>>               info = @Info(




>>>>>>                       description = "Sample2 server",




>>>>>>                       version="1.0",




>>>>>>                       title = "Test2",




>>>>>>                       contact = @Contact(name = "J.P.
>>>>>> Urkens",email =
JPU> "



>>>>>>       *jean-pierre.urkens@devoteam.com* <

>>>>> jean-pierre.urkens@devoteam.com>



>>>>>>       ")),




>>>>>>               securityDefinition =



>>>>>>       @SecurityDefinition(apiKeyAuthDefinitions=



>>>>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name
>>>>> =
JPU> <*%7B@ApiKeyAuthDefinition(key=>

>>>>> "A

>>>>> u

>>>>> thorization",description="Use*



>>>>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer



>>>>>>       &lt;accessToken&gt;'")})




>>>>>>       )




>>>>>>       public class Sample2 {...}




>>>>>> This correctly generates the ‘securityDefintions’ in the swagger
>>>>>> file.




>>>>>> If include the same @SwaggerDefinition and the authorizations on



>>>>>> the @Api annotation as above in my interface classes then the



>>>>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?




>>>>>> Any idea what I might be missing?




>>>>>> Regards,




>>>>>> J.P.




>>>>>> -----Original Message-----



>>>>>> From: Jean Pierre URKENS <je...@devoteam.com>



>>>>>> Sent: dinsdag 23 mei 2023 12:52



>>>>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <



>>>>>> Subject: RE: How to setup multiple JAXRS server endpoints




>>>>>> Hi Andriy,




>>>>>> I added the parameter usePathBasedConfig=true to the



>>>>>> Swagger2Feature bean declarations but still it does generate an



>>>>>> empty swagger.yaml for interfaces KmopResources and



>>>>>> KmopDienstverlener although I noticed that for these interfaces

>>>>>> the



>>>>>> @Path() annotation was commented out (as I included it in the



>>>>>> server declaration). After providing an empty @Path("")

>>>>>> declaration on

>>>>> the API interface classes everything worked.




>>>>>> Thanks for the support.




>>>>>> -----Original Message-----




>>>>>> From: Andriy Redko <dr...@gmail.com>




>>>>>> Sent: dinsdag 23 mei 2023 3:42




>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;



>>>>>> dev@cxf.apache.org




>>>>>> Subject: Re: How to setup multiple JAXRS server endpoints




>>>>>> Hi Jean,




>>>>>> The main problem to configure Swagger property in your particular



>>>>>> case is that the server address is not "known" or "introspectable"

>>>>>> for

>>>>> Swagger.



>>>>>> Intuitively, it has to be set manually using basePath to the,



>>>>>> essentially, the server address




>>>>>> part:




>>>>>>  - /op/services/accounts




>>>>>>  - /op/services/resources




>>>>>>  - /op/services/dienstverlener




>>>>>> You could read more about other Swagger properties you have asked
JPU> here:



>>>>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---In
>>>>>> t

>>>>>> e



>>>>>> gration-and-Configuration#configuration-properties




>>>>>> You definitely need to set usePathBasedConfig to "true" otherwise



>>>>>> you will see the same Swagger specs for all servers. We have a



>>>>>> sample here which uses 2 jaxrs:server




>>>>>> instances:



>>>>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m
>>>>>> a

>>>>>> i



>>>>>> n/release/samples/jax_rs/description_swagger2_web




>>>>>> Regarding SwaggerUI, I think the value for each of those should
>>>>>> be



>>>>>> set to,



>>>>>> respectively:




>>>>>>  - /op/services/accounts/swagger.yaml




>>>>>>  - /op/services/resources/swagger.yaml




>>>>>>  - /op/services/dienstverlener/swagger.yaml




>>>>>> I believe this is matching your settings already, except the



>>>>>> usePathBasedConfig part. The example referred above could be



>>>>>> helpful, my apologies if I missed something, there are quite a
>>>>>> lot



>>>>>> of questions :-) The fact that the generated Swagger
>>>>>> specification



>>>>>> is empty is unexpected - it should not happen when JAX-RS

>>>>>> resources

>>>>> are properly configured.




>>>>>> Thank you.




>>>>>> Best Regards,




>>>>>>     Andriy Redko




>>>>>>>  RE: How to setup multiple JAXRS server endpoints




>>>>>>> Hi Andriy,




>>>>>>> I am not quite understanding how to correctly configure the



>>>>>> Swagger2Feature.




>>>>>>> Referring to the attached cxf-endpoints configuration I (as a



>>>>>>> test)




>>>>>>> created




>>>>>>> 3 JAXRS server instances:




>>>>>>> 1.      A* KmopApiServer* server for the*




>>>>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving




>>>>>>> requests for URI path:




>>>>>>>        * <protocol>**//<host:<port>/op/services/accounts*




>>>>>>>    ‘op’  = root path of the web application




>>>>>>>             ‘services’ = servlet path of the CXF-servlet




>>>>>>>       The address of the server is set to ‘/accounts’ and the



>>>>>>> @Path(…)




>>>>>>>       annotation on the interface class was cleared.




>>>>>>> 2.      A* Kmop**Resources**ApiServer* server for the*

>>>>> be.dvtm.aeo.op.*




>>>>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving




>>>>>>> requests for URI path:




>>>>>>>        * <protocol>**//<host:<port>/op/services/**resources*




>>>>>>> The address of the server is set to ‘/resources’ and the
>>>>>>> @Path(…)




>>>>>>> annotation on the interface class was cleared.




>>>>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*



>>>>>> be.dvtm.aeo.op.*




>>>>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving




>>>>>>> requests for URI path:




>>>>>>>        *
>>>>>>> <protocol>**//<host:<port>/op/services/**dienstverlener*




>>>>>>> The address of the server is set to ‘/dienstverlener’ and the




>>>>>>> @Path(…) annotation on the interface class was cleared.




>>>>>>> For each of these server instances I’ve set the Swagger2Feature




>>>>>>> with configuration as indicated in the attached cxf-endpoints.xml.




>>>>>>> With regard to the configurations for the Swagger2Feature I’ve

>>>>>>> the




>>>>>>> following questions:




>>>>>>> a)      Referring to *

>>>>> https://cxf.apache.org/docs/swagger2feature.html*




>>>>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you




>>>>>>> clarify on the following configuration parameters:




>>>>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘




>>>>>>> /op/services’) or to the JAX-RS server instance (e.g.




>>>>>>> ‘/op/services/accounts’) or still something else? Is it used to




>>>>>>> resolve service classes or is it just for documentation in the



>>>>>>> swagger



>>>>>> file?




>>>>>>> *ii.    ** resourcePackage* – the description mentions ‘package
JPU> names’




>>>>>>> while the default mentions ‘service classes’? Service 2 and 3



>>>>>>> above




>>>>>>> are within the same package (generated from the same yaml




>>>>>>> specification that included both interfaces).




>>>>>>> *iii.   ** ig**noreRoutes* – is this taken into account when




>>>>>>> scanAllResources=false?




>>>>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter

>>>>> value




>>>>>>> (cf. question ‘a’)?




>>>>>>> b)      What would be the correct URL to generate a swagger.yaml

>>>>>>> file



>>>>>> for




>>>>>>> each of the above interfaces? Initially I called:




>>>>>>> *i.     **



>>>>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*




>>>>>>> *ii.    **



>>>>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*




>>>>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*




>>>>>>> *lener/swagger.yaml*




>>>>>>>    All three requests delivered the same yaml specification,



>>>>>>> namely



>>>>>> the one




>>>>>>>       for interface* KmopApiServer*?




>>>>>>> c)      I tried to debug the processing of the requests under ‘b)’

>>>>>>> and



>>>>>> this




>>>>>>> is done by the class JAXRSInterceptor#processRequest where the




>>>>>>> MessageImpl object for request “ii.” looks like the one attached.




>>>>>>> It finds 3 resource




>>>>>>> classes:




>>>>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl




>>>>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource




>>>>>>>       org.apache

Re: Request mapping warnings

Posted by Andriy Redko <dr...@gmail.com>.
Hi Jean,

The issue with duplicate beans registration comes from JAXRS server definition:

        <jaxrs:server id="KmopOpenApiServer" basePackages="be.dvtm.aeo.op.openapi" address="/openapi">

The basePackages property triggers automatic scans which basically means that the same beans will be 
discovered twice. I think you could safely bring the @Service annotation back and remove basePackages
property to get rid of the issue. 

Thanks!

Best Regards,
    Andriy Redko

JPU> No, I am not using SpringBoot in any way.



JPU> Regards,



JPU> J.P.



JPU> *From:* Andrey Redko <dr...@gmail.com>
JPU> *Sent:* donderdag 20 juli 2023 15:24
JPU> *To:* Jean Pierre URKENS <je...@devoteam.com>
JPU> *Cc:* Daniel Kulp <de...@cxf.apache.org>
JPU> *Subject:* Re: Request mapping warnings



JPU> Hi Jean,



JPU> Do you use CXF Spring Boot autoconfiguration [1]? If yes, it has a few
JPU> controls over scans [1], either beans or classes (I am off this week so
JPU> cannot look into the configuration). Thank you.


JPU> [1] https://cxf.apache.org/docs/springboot.html

JPU> Best Regards,
JPU>     Andriy Redko



JPU> On Thu, Jul 20, 2023, 2:23 AM Jean Pierre URKENS <
JPU> jean-pierre.urkens@devoteam.com> wrote:

JPU> Hi all,



JPU> As a test I removed the @org.springframework.stereotype.Service(“
JPU> *KmopDienstverlenerApi*”) annotation on my service implementation class. So
JPU> no @Service annotations further exist. Still when checking the return of
JPU> *JAXRSUtils.**getRootResources*(Message message) via breakpoint I

JPU> Still notice that my service classes are listed twice in the return result
JPU> *List<ClassResourceInfo>*.



JPU> The only annotations I’ve left in my code are:

JPU>    - standard JAX-RS annotations:
JPU>    javax.ws.rs.[GET|POST|Consumes|Produces|HeaderParam|PathParam|QueryParam|Path|core.MediaType|core.Response]
JPU>    - io.swagger.v3.oas.annotations.*

JPU> I suppose none of these would be responsible for an extra registration of
JPU> my service classes.



JPU> So the only point where service registration occurs is in the bean
JPU> declaration file cxf-endpoint.xml, see attachment. The only thing I can
JPU> think of a possible double registration in this file is the declaration of
JPU> the OpenApiFeature (e.g. <bean id=”*KmopOpenApiFeature*” …> ) for each
JPU> resource endpoint in addition to the <jaxrs:server /> declaration using
JPU> this OpenApiFeature.

JPU> But I would assume that configuring the OpenApiFeature, through a bean
JPU> declaration, wouldn’t register a service.



JPU> The ‘imported’ resources context-v2.xml and onderneming-context.xml define
JPU> some <jaxws:client/> instances that have nothing to do with these JAX-WS/RS
JPU> endpoints declared in this file.



JPU> Is there something I can trace into to see when a service gets registered
JPU> as a *ClassResourceInfo *?



JPU> Regards,



JPU> J.P. Urkens

JPU> *From:* Andrey Redko <dr...@gmail.com>
JPU> *Sent:* woensdag 19 juli 2023 19:30
JPU> *To:* Jean Pierre URKENS <je...@devoteam.com>
JPU> *Cc:* Daniel Kulp <de...@cxf.apache.org>
JPU> *Subject:* Re: Request mapping warnings



JPU> Hi Jean,



JPU> Indeed it looks like you have the same resource registered twice hence the
JPU> warning. It may come from the use of automatic resource scans and manual
JPU> resource registration.

JPU> Best Regards,
JPU>     Andriy Redko



JPU> On Wed, Jul 19, 2023, 7:39 AM Jean Pierre URKENS <
JPU> jean-pierre.urkens@devoteam.com> wrote:

JPU> Still some minor issue related to request mapping.

JPU> I notice I am getting warnings like:

JPU> *2023-07-19 13:08:23,022 [T8N1TP1-4] WARN
JPU> (SID=8806F673DEC6B53D9248AF0DD81F6882)
JPU> (org.apache.cxf.jaxrs.model.OperationResourceInfoComparatorBase:102) - Both
JPU> be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#getDvlById
JPU> and
JPU> be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#getDvlById
JPU> are equal candidates for handling the current request which can lead to
JPU> unpredictable results*

JPU> Obvious that they are equal candidates because they are the same class. But
JPU> what is the cause of this double detection?

JPU> Is it because when *JAXRSUtils.**getRootResources*(Message message)  gets
JPU> called, I see that it contains 4 entries:

JPU> ·       (twice) KmopDienstverlenerApiServiceImpl -> my service endpoint

JPU> ·       io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

JPU> ·       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService

JPU> So twice my service implementation, I wouldn’t know why this is the case?

JPU> On my classpath I have set:

JPU> ·       cxf-rt-rs-service-description-3.5.6.jar                 -> this
JPU> handles request for ‘_wadl’

JPU> ·       cxf-rt-rs-service-description-openapi-v3-3.5.6.jar      -> this
JPU> handles request for ‘openapi.[yaml|json]’

JPU> ·       cxf-rt-rs-service-description-swagger-ui-3.5.6.jar      -> this
JPU> handles request for ‘Swagger documentation’

JPU> would this be a cause for my service endpoint to appear multiple times?
JPU> Aside from that I have no idea what could cause this.

JPU> J.P.

JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: donderdag 13 juli 2023 18:24
JPU> To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Got it, thank you (the Swagger sometimes does surprising things).

JPU> Thursday, July 13, 2023, 1:33:07 AM, you wrote:

JPU>> The @Parameter annotation seems to be ignored at this level.

JPU>> -----Original Message-----

JPU>> From: Jean Pierre URKENS <je...@devoteam.com>

JPU>> Sent: donderdag 13 juli 2023 7:11

JPU>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'

JPU>> <de...@cxf.apache.org>

JPU>> Subject: RE: How to setup multiple JAXRS server endpoints

JPU>> Yes, SwaggerUI works too!

JPU>> I noticed that v2.x of swagger-jaxrs relates to OpenApi v3.1.x

JPU>> while my spec is compliant with OpenApi v3.0.x, so I am going to

JPU>> stick with v2.1.13 which seems to be that last version for OpenApi
JPU> v3.0.x.

JPU>> I thought the @Parameter only applied to input parameters ("query",

JPU>> "header", "path" or "cookie" parameters), but I'll give it a try.

JPU>> J.P.

JPU>> -----Original Message-----

JPU>> From: Andriy Redko <dr...@gmail.com>

JPU>> Sent: woensdag 12 juli 2023 22:16

JPU>> To: Jean Pierre URKENS <je...@devoteam.com>;

JPU>> dev@cxf.apache.org

JPU>> Subject: Re: How to setup multiple JAXRS server endpoints

JPU>> Hi Jean,

JPU>> That's awesome, have you got SwaggerUI working as well?

JPU>> Yes, you could use 2.2.15 (we already updated to this version, no

JPU>> regressions). It seems like the description applies to the whole

JPU>> schema (which is the same for both properties), may be you could

JPU>> use @Parameter

JPU>> instead:

JPU>> @Parameter(description="The description I want for prop1")

JPU>> Thank you.

JPU>> Best Regards,

JPU>>     Andriy Redko

>>> Hi Andriy,

>>> After having migrated everything to "io.swagger.v3.oas.annotations.*"

>>> the swagger endpoints for each of my services became active.

>>> So far so good, but I do notice that there are discrepancies when

>>> annotating models, e.g.:

>>>  public class Model1 {

>>>   @Schema(description="The description I want for prop1")

>>>    private Model2 prop1;

>>>   @Schema(description="The description I want for prop2")

>>>    private Model2 prop2;

>>>   ...

>>> }

>>> When I generate the openapi.[json|yaml] specification I see that both

>>> prop1 and prop2 have a reference to the schema component "Model2"

>>> with description ' The description I want for prop2' which is

>>> inappropriate for 'prop1'.

>>> It is not unlikely to have multiple properties within one Model that

>>> are of the same class but are semantically used in a different context.
JPU> E.g.

>>> something as simple as a ShipmentOrder having two 'Address'

>>> properties 'from' and 'to' would result in wrong API documentation.

>>> I am aware it has nothing to do with CXF but rather with

>>> swagger-jaxrs2-vx.y.z.jar and depending libraries. CXF-3.5.6 has

>>> dependency on swagger-jaxrs2-2.1.13.jar. Would it be an issue to

>>> replace this dependency with e.g. swagger-jaxrs2-2.2.15.jar (latest

>>> stable release according to maven central repo)?

>>> J.P.

>>> -----Original Message-----

>>> From: Jean Pierre URKENS <je...@devoteam.com>

>>> Sent: woensdag 12 juli 2023 8:25

>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'

>>> <de...@cxf.apache.org>

>>> Subject: RE: How to setup multiple JAXRS server endpoints I seem to

>>> be mistaken here, the endpoint was loaded (I did a manual HTTP GET

>>> test to the endpoint to verify this) although no breakpoints where

>>> hit during startup.

>>> I am first going to complete the migration to

>>> "io.swagger.v3.oas.annotations.*" annotations for all endpoints and

>>> then I am going to test again.

>>> The application is composed of libraries, some of which use SLF4J but

>>> most use LOG4J for logging.

>>> J.P.

>>> -----Original Message-----

>>> From: Andriy Redko <dr...@gmail.com>

>>> Sent: woensdag 12 juli 2023 1:13

>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>> dev@cxf.apache.org

>>> Subject: Re: How to setup multiple JAXRS server endpoints Hi Jean,

>>> The

>>> OpenApiFeature$Portable#initiliaze(…) should definitely be called

>>> (otherwise you shouldn't even see the openapi.json endpoint), so I am

>>> not sure why these are not triggering for you.

>>>

>>> For logging, it seems like you are using SLF4J

>>> (org.apache.cxf.common.logging.Slf4jLogger),

>>> and also reload4j (aka log4j), why do you need both?

>>> Thank you.

>>> Best Regards,

>>>     Andriy Redko

JPU>>>> After some code investigation:



JPU>>>> OpenApiFeature implements SwaggerUiSupport and in its

JPU>>>> portable#registerSwaggerUiResources(…) method it will call

JPU>>>> SwaggerUiSupport#getSwaggerUi(…) which will register the

JPU>> SwaggerUiService.



JPU>>>> I have put breakpoints on:

JPU>>>>    - OpenApiFeature$Portable#initiliaze(…)

JPU>>>>    - SwaggerUiService constructor

JPU>>>>    - SwaggerUiSupport#getSwaggerUi(…)



JPU>>>> but none of them are hit when starting my application?



JPU>>>> Although the (spring) logging shows all beans in my

JPU>>>> cxf-endpoints.xml have been created?

JPU>>>> The *WADL* and *OpenAPI* endpoints to get the specification work.

JPU>>>> Even the actual endpoint seems to work although I didn’t hit any

JPU>>>> of the breakpoint?



JPU>>>> CXF, also doesn’t seem to log a lot, I am hardly getting any log

JPU>>>> entries although log level I set to DEBUG.

JPU>>>> My logging (except wire message logging) for cxf is setup

JPU>>>> correctly (I

JPU>>>> think):

JPU>>>>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line

JPU>>>>    ‘org.apache.cxf.common.logging.Slf4jLogger’

JPU>>>>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and

JPU>>>>    reload4j-1.2.19.jar are on the classpath

JPU>>>>    - the log4j.properties file contains the line:

JPU>>>>    ‘log4j.logger.org.apache.cxf=DEBUG’



JPU>>>> There are no special instructions mentioned on

JPU>>>> https://cxf.apache.org/docs/general-cxf-logging.html so the above

JPU>>>> should work (it works for all other packages I use in my
JPU> application).



JPU>>>> J.P.

JPU>>>> *From:* Jean Pierre URKENS <je...@devoteam.com>

JPU>>>> *Sent:* dinsdag 11 juli 2023 9:58

JPU>>>> *To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <

dev@cxf.apache.org>>>>>

JPU>>>> *Subject:* RE: How to setup multiple JAXRS server endpoints



JPU>>>> Hi Andriy,



JPU>>>> As a test I removed all JAX-RS endpoints that use Swagger v2

JPU>>>> annotations from my configuration file (see attachment).

JPU>>>> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger

JPU>>>> v3 annotations, using the OpenApiFeature i.o. Swagger2Feature.

JPU>>>> If I run my server with this configuration I only get the

JPU>>>> (working)

JPU>>>> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint:



JPU>>>> So there is some configuration missing to detect/activate the

JPU>>>> Swagger endpoint. When I look at the samples that come with the

JPU>>>> distribution of CXF (I am using v3.5.6) nothing special seems to

JPU>>>> be

JPU>> configured to activate this?

JPU>>>> Do you have any idea how the SwaggerUiService is picked up when

JPU>> loading?



JPU>>>> J.P.



JPU>>>> -----Original Message-----

JPU>>>> From: Andriy Redko <dr...@gmail.com>

JPU>>>> Sent: dinsdag 11 juli 2023 3:44

JPU>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

JPU>>>> dev@cxf.apache.org

JPU>>>> Subject: Re: How to setup multiple JAXRS server endpoints



JPU>>>> Hi Jean,



JPU>>>> I guess you figured one issue, swagger.json -> openapi.json, but

JPU>>>> to be honest we have never tested or envisioned the application

JPU>>>> that would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same

JPU>>>> time, I am afraid this is just not supported. You may get things

JPU>>>> back on track when going with OpenAPI 3.0 for all services.



JPU>>>> Thank you.



JPU>>>> Best Regards,

JPU>>>>     Andriy Redko



>>>>> Hi Andriy,




>>>>> I am trying to trace the difference in handling with another

>>>>> application where I’ve got only one CXF service endpoint that uses

>>>>> swagger v3 openapi annotations.



>>>>> There I see that when handling the Swagger page request (

>>>>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json)

>>>>> the JAXRSInInterceptor is calling:




>>>>> *JAXRSUtils.**getRootResources*(Message message)




>>>>> It contains 4 entries:



>>>>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint

>>>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

>>>>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService












>>>>> On the application described below with the service ‘oidcsim’ when

>>>>> calling the swagger page request

>>>>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the

>>>>> result of the getRootResources doesn’t contain the

>>>>> ClassResourceInfo ‘ SwaggerUiService’. It only contains 3 entries:



>>>>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)

>>>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource




>>>>> The SwaggerUiService is the one that is configured to handle the

JPU>>>> ‘api-docs’

>>>>> path-request. Since it is missing the request is tried to match

>>>>> with the other two resources but fails, hence ‘NOT FOUND’ exception.




>>>>> I can’t trace back where these rootResources are set and why the

>>>>> SwaggerUiService’ isn’t listed.




>>>>> J.P.



>>>>> *From:* Jean Pierre URKENS <je...@devoteam.com>

>>>>> *Sent:* maandag 10 juli 2023 13:43

>>>>> *To:* 'Andriy Redko' <dr...@gmail.com>

>>>>> *Subject:* RE: How to setup multiple JAXRS server endpoints




>>>>> Andriy,




>>>>> I am trying to switch from Swagger v2 to OpenApi v3 annotations

>>>>> basically because my starting point is an OpenApi v3.0.7 yaml file

>>>>> description and OpenAPI seems to be the way forward.



>>>>> For applications where I have only one CXF JAX-RS endpoint exposed

>>>>> I had no problems converting. However as soon as there are multiple

>>>>> endpoints I run into troubles.




>>>>> So, to recall, I've an application exposing 3 JAX-RS endpoints that

>>>>> where previously annotated with swagger v2 annotations (i.e.

>>>>> package

>>>>> io.swagger.annotations.*) which I migrated to



>>>>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*).

>>>>> In accordance I altered my CXF JAX-RS endpoint configuration from

>>>>> (only showing relevant parts, see attachment for full setup):




>>>>>                <!-- CXF Swagger2Feature -->



>>>>>                <bean id="SwaggerUiConfigOidcApi"

>>>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>>>>>                               <property name="queryConfigEnabled"



>>>>>                               <property name="url"

>>>>> value="/op/services/oidcsim/swagger.yaml"/>



>>>>>                </bean>



>>>>>                <bean id="Swagger2FeatureOidcApi"

>>>>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">



>>>>>                               <property name="basePath"

>>>>> value="/op/services/oidcsim"/>



>>>>>                               <property name="usePathBasedConfig"



>>>>>                               <property name="resourcePackage"

>>>>> value="be.dvtm.aeo.op.oidc"/>



>>>>>                               <property name="supportSwaggerUi"



>>>>>                               <property name="swaggerUiConfig"

>>>>> ref="SwaggerUiConfigOidcApi"/>



>>>>>                </bean>



>>>>>                <jaxrs:server id="OidcProviderApiServer"

>>>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>>>>>                               ....



>>>>>                               <jaxrs:features>



>>>>>                                              <ref

>>>>> bean="Swagger2FeatureOidcApi" />



>>>>>                               </jaxrs:features>



>>>>>                               ...



>>>>>                </jaxrs:server>




>>>>> TO:



>>>>>                <!-- CXF OpenAPIFeature -->



>>>>>                <bean id="OidcSwaggerUiConfig"

>>>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>>>>>                               <property name="queryConfigEnabled"



>>>>>                               <property name="url"

>>>>> value="openapi.json"/>



>>>>>                </bean>



>>>>>                <bean id="OidcOpenApiFeature"

>>>>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">



>>>>>                               <property name="supportSwaggerUi"



>>>>>                               <property name="swaggerUiConfig"

>>>>> ref="OidcSwaggerUiConfig"/>



>>>>>                               <property name="swaggerUiVersion"



>>>>>                               <property name="scan" value="false"/>



>>>>>                               <property name="useContextBasedConfig"



>>>>>                               <property name="resourcePackages"

>>>>> value="be.dvtm.aeo.op.oidc"/>



>>>>>                </bean>



>>>>>                <jaxrs:server id="OidcProviderApiServer"

>>>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>>>>>                               ....



>>>>>                               <jaxrs:features>



>>>>>                                              <ref

JPU>>>> bean="OidcOpenApiFeature"



>>>>>                               </jaxrs:features>



>>>>>                               ...



>>>>>                </jaxrs:server>








>>>>> Now when starting my application and navigating to the root part "

>>>>> http://localhost:localPort/op/services" I get an overview of all my

>>>>> endpoints:




>>>>> Now there are 3 RESTful service endpoints setup:



>>>>>    1. ‘oidcsim’ which I switched to swagger v3 annotations

>>>>>    2. ‘openapi’ currently still swagger v2 annotations

>>>>>    3. ‘sdx’ currently still swagger v2 annotations




>>>>> all endpoints work except for the ‘swagger endpoint address for the

>>>>> oidcsim

>>>>> endpoint:

>>>>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services

>>>>> /o

>>>>> i

>>>>> dcsim/swagger.json



>>>>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*

>>>>> endpoint of the oidcsim resource. I am getting an error (the value

>>>>> of the ‘url’ query parameter isn’t relevant):




>>>>>         “WebApplicationException has been caught, status: 404,

>>>>> message: HTTP 404 Not Found”




>>>>> When I try (without the ‘/oidcsim’ context):

>>>>> http://l-p53-008:8081/op/services/api-docs I get:



>>>>>                “No service was found.”




>>>>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs

>>>>> doesn’t exist, where as the endpoint

>>>>> http://l-p53-008:8081/op/services/api-docs does exist but no

>>>>> service

JPU>>>> description is found?



>>>>> Of course my intention is to get working, as previously with the

>>>>> swagger v2 setup for which I then specifically added the

>>>>> *Swagger2Feature* config

>>>>> parameters:



>>>>>                               <property name="basePath"

>>>>> value="/op/services/oidcsim"/>



>>>>>                               <property name="usePathBasedConfig"




>>>>> But I don’t find the according configuration options for the

>>>>> *OpenApiFeature* class or whether I should configure this in

>>>>> another way.




>>>>> Any suggestions on this?




>>>>> Regards,




>>>>> J.P.








>>>>> -----Original Message-----

>>>>> From: Andriy Redko <dr...@gmail.com>

>>>>> Sent: donderdag 25 mei 2023 2:27

>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>>>> dev@cxf.apache.org

>>>>> Subject: Re: How to setup multiple JAXRS server endpoints




>>>>> Hi Jean,




>>>>> You may run into Swagger JAX-RS scanner limitations, as far as I

>>>>> can tell - it checks class annotations for SwaggerDefinition, does

>>>>> not traverse the hierarchy [1].




>>>>> [1]

>>>>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagge

>>>>> r-

>>>>> j

>>>>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194




>>>>> Best Regards,



>>>>>     Andriy Redko




>>>>>>  RE: How to setup multiple JAXRS server endpoints




>>>>>> Still one question );




>>>>>> The generated swagger file doesn’t take into account the



>>>>>> @SwaggerDefintion on my interface classes?




>>>>>> As a test I looked at



>>>>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m

>>>>>> a



>>>>>> in/release/samples/jax_rs/description_swagger2_web**



>>>>>> and** modified** sample2*



>>>>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m

>>>>>> a



>>>>>> in/release/samples/jax_rs/description_swagger2_web



>>>>>> and modified sample2> as follows:




>>>>>>    @Path("/sample2")




>>>>>>       @Api(value = "/sample2",authorizations=



>>>>>>       {@Authorization(value="bearer")},description = "Sample2

>>>>> (modified) JAX-RS



>>>>>>       service with Swagger documentation")




>>>>>>       @SwaggerDefinition(




>>>>>>               info = @Info(




>>>>>>                       description = "Sample2 server",




>>>>>>                       version="1.0",




>>>>>>                       title = "Test2",




>>>>>>                       contact = @Contact(name = "J.P. Urkens",email =
JPU> "



>>>>>>       *jean-pierre.urkens@devoteam.com* <

>>>>> jean-pierre.urkens@devoteam.com>



>>>>>>       ")),




>>>>>>               securityDefinition =



>>>>>>       @SecurityDefinition(apiKeyAuthDefinitions=



>>>>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name=
JPU> <*%7B@ApiKeyAuthDefinition(key=>

>>>>> "A

>>>>> u

>>>>> thorization",description="Use*



>>>>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer



>>>>>>       &lt;accessToken&gt;'")})




>>>>>>       )




>>>>>>       public class Sample2 {...}




>>>>>> This correctly generates the ‘securityDefintions’ in the swagger file.




>>>>>> If include the same @SwaggerDefinition and the authorizations on



>>>>>> the @Api annotation as above in my interface classes then the



>>>>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?




>>>>>> Any idea what I might be missing?




>>>>>> Regards,




>>>>>> J.P.




>>>>>> -----Original Message-----



>>>>>> From: Jean Pierre URKENS <je...@devoteam.com>



>>>>>> Sent: dinsdag 23 mei 2023 12:52



>>>>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <



>>>>>> Subject: RE: How to setup multiple JAXRS server endpoints




>>>>>> Hi Andriy,




>>>>>> I added the parameter usePathBasedConfig=true to the



>>>>>> Swagger2Feature bean declarations but still it does generate an



>>>>>> empty swagger.yaml for interfaces KmopResources and



>>>>>> KmopDienstverlener although I noticed that for these interfaces

>>>>>> the



>>>>>> @Path() annotation was commented out (as I included it in the



>>>>>> server declaration). After providing an empty @Path("")

>>>>>> declaration on

>>>>> the API interface classes everything worked.




>>>>>> Thanks for the support.




>>>>>> -----Original Message-----




>>>>>> From: Andriy Redko <dr...@gmail.com>




>>>>>> Sent: dinsdag 23 mei 2023 3:42




>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;



>>>>>> dev@cxf.apache.org




>>>>>> Subject: Re: How to setup multiple JAXRS server endpoints




>>>>>> Hi Jean,




>>>>>> The main problem to configure Swagger property in your particular



>>>>>> case is that the server address is not "known" or "introspectable"

>>>>>> for

>>>>> Swagger.



>>>>>> Intuitively, it has to be set manually using basePath to the,



>>>>>> essentially, the server address




>>>>>> part:




>>>>>>  - /op/services/accounts




>>>>>>  - /op/services/resources




>>>>>>  - /op/services/dienstverlener




>>>>>> You could read more about other Swagger properties you have asked
JPU> here:



>>>>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Int

>>>>>> e



>>>>>> gration-and-Configuration#configuration-properties




>>>>>> You definitely need to set usePathBasedConfig to "true" otherwise



>>>>>> you will see the same Swagger specs for all servers. We have a



>>>>>> sample here which uses 2 jaxrs:server




>>>>>> instances:



>>>>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma

>>>>>> i



>>>>>> n/release/samples/jax_rs/description_swagger2_web




>>>>>> Regarding SwaggerUI, I think the value for each of those should be



>>>>>> set to,



>>>>>> respectively:




>>>>>>  - /op/services/accounts/swagger.yaml




>>>>>>  - /op/services/resources/swagger.yaml




>>>>>>  - /op/services/dienstverlener/swagger.yaml




>>>>>> I believe this is matching your settings already, except the



>>>>>> usePathBasedConfig part. The example referred above could be



>>>>>> helpful, my apologies if I missed something, there are quite a lot



>>>>>> of questions :-) The fact that the generated Swagger specification



>>>>>> is empty is unexpected - it should not happen when JAX-RS

>>>>>> resources

>>>>> are properly configured.




>>>>>> Thank you.




>>>>>> Best Regards,




>>>>>>     Andriy Redko




>>>>>>>  RE: How to setup multiple JAXRS server endpoints




>>>>>>> Hi Andriy,




>>>>>>> I am not quite understanding how to correctly configure the



>>>>>> Swagger2Feature.




>>>>>>> Referring to the attached cxf-endpoints configuration I (as a



>>>>>>> test)




>>>>>>> created




>>>>>>> 3 JAXRS server instances:




>>>>>>> 1.      A* KmopApiServer* server for the*




>>>>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving




>>>>>>> requests for URI path:




>>>>>>>        * <protocol>**//<host:<port>/op/services/accounts*




>>>>>>>    ‘op’  = root path of the web application




>>>>>>>             ‘services’ = servlet path of the CXF-servlet




>>>>>>>       The address of the server is set to ‘/accounts’ and the



>>>>>>> @Path(…)




>>>>>>>       annotation on the interface class was cleared.




>>>>>>> 2.      A* Kmop**Resources**ApiServer* server for the*

>>>>> be.dvtm.aeo.op.*




>>>>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving




>>>>>>> requests for URI path:




>>>>>>>        * <protocol>**//<host:<port>/op/services/**resources*




>>>>>>> The address of the server is set to ‘/resources’ and the @Path(…)




>>>>>>> annotation on the interface class was cleared.




>>>>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*



>>>>>> be.dvtm.aeo.op.*




>>>>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving




>>>>>>> requests for URI path:




>>>>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*




>>>>>>> The address of the server is set to ‘/dienstverlener’ and the




>>>>>>> @Path(…) annotation on the interface class was cleared.




>>>>>>> For each of these server instances I’ve set the Swagger2Feature




>>>>>>> with configuration as indicated in the attached cxf-endpoints.xml.




>>>>>>> With regard to the configurations for the Swagger2Feature I’ve

>>>>>>> the




>>>>>>> following questions:




>>>>>>> a)      Referring to *

>>>>> https://cxf.apache.org/docs/swagger2feature.html*




>>>>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you




>>>>>>> clarify on the following configuration parameters:




>>>>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘




>>>>>>> /op/services’) or to the JAX-RS server instance (e.g.




>>>>>>> ‘/op/services/accounts’) or still something else? Is it used to




>>>>>>> resolve service classes or is it just for documentation in the



>>>>>>> swagger



>>>>>> file?




>>>>>>> *ii.    ** resourcePackage* – the description mentions ‘package
JPU> names’




>>>>>>> while the default mentions ‘service classes’? Service 2 and 3



>>>>>>> above




>>>>>>> are within the same package (generated from the same yaml




>>>>>>> specification that included both interfaces).




>>>>>>> *iii.   ** ig**noreRoutes* – is this taken into account when




>>>>>>> scanAllResources=false?




>>>>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter

>>>>> value




>>>>>>> (cf. question ‘a’)?




>>>>>>> b)      What would be the correct URL to generate a swagger.yaml

>>>>>>> file



>>>>>> for




>>>>>>> each of the above interfaces? Initially I called:




>>>>>>> *i.     **



>>>>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*




>>>>>>> *ii.    **



>>>>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*




>>>>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*




>>>>>>> *lener/swagger.yaml*




>>>>>>>    All three requests delivered the same yaml specification,



>>>>>>> namely



>>>>>> the one




>>>>>>>       for interface* KmopApiServer*?




>>>>>>> c)      I tried to debug the processing of the requests under ‘b)’

>>>>>>> and



>>>>>> this




>>>>>>> is done by the class JAXRSInterceptor#processRequest where the




>>>>>>> MessageImpl object for request “ii.” looks like the one attached.




>>>>>>> It finds 3 resource




>>>>>>> classes:




>>>>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl




>>>>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource




>>>>>>>       org.apache


RE: Request mapping warnings

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
No, I am not using SpringBoot in any way.



Regards,



J.P.



*From:* Andrey Redko <dr...@gmail.com>
*Sent:* donderdag 20 juli 2023 15:24
*To:* Jean Pierre URKENS <je...@devoteam.com>
*Cc:* Daniel Kulp <de...@cxf.apache.org>
*Subject:* Re: Request mapping warnings



Hi Jean,



Do you use CXF Spring Boot autoconfiguration [1]? If yes, it has a few
controls over scans [1], either beans or classes (I am off this week so
cannot look into the configuration). Thank you.


[1] https://cxf.apache.org/docs/springboot.html

Best Regards,
    Andriy Redko



On Thu, Jul 20, 2023, 2:23 AM Jean Pierre URKENS <
jean-pierre.urkens@devoteam.com> wrote:

Hi all,



As a test I removed the @org.springframework.stereotype.Service(“
*KmopDienstverlenerApi*”) annotation on my service implementation class. So
no @Service annotations further exist. Still when checking the return of
*JAXRSUtils.**getRootResources*(Message message) via breakpoint I

Still notice that my service classes are listed twice in the return result
*List<ClassResourceInfo>*.



The only annotations I’ve left in my code are:

   - standard JAX-RS annotations:
   javax.ws.rs.[GET|POST|Consumes|Produces|HeaderParam|PathParam|QueryParam|Path|core.MediaType|core.Response]
   - io.swagger.v3.oas.annotations.*

I suppose none of these would be responsible for an extra registration of
my service classes.



So the only point where service registration occurs is in the bean
declaration file cxf-endpoint.xml, see attachment. The only thing I can
think of a possible double registration in this file is the declaration of
the OpenApiFeature (e.g. <bean id=”*KmopOpenApiFeature*” …> ) for each
resource endpoint in addition to the <jaxrs:server /> declaration using
this OpenApiFeature.

But I would assume that configuring the OpenApiFeature, through a bean
declaration, wouldn’t register a service.



The ‘imported’ resources context-v2.xml and onderneming-context.xml define
some <jaxws:client/> instances that have nothing to do with these JAX-WS/RS
endpoints declared in this file.



Is there something I can trace into to see when a service gets registered
as a *ClassResourceInfo *?



Regards,



J.P. Urkens

*From:* Andrey Redko <dr...@gmail.com>
*Sent:* woensdag 19 juli 2023 19:30
*To:* Jean Pierre URKENS <je...@devoteam.com>
*Cc:* Daniel Kulp <de...@cxf.apache.org>
*Subject:* Re: Request mapping warnings



Hi Jean,



Indeed it looks like you have the same resource registered twice hence the
warning. It may come from the use of automatic resource scans and manual
resource registration.

Best Regards,
    Andriy Redko



On Wed, Jul 19, 2023, 7:39 AM Jean Pierre URKENS <
jean-pierre.urkens@devoteam.com> wrote:

Still some minor issue related to request mapping.

I notice I am getting warnings like:

*2023-07-19 13:08:23,022 [T8N1TP1-4] WARN
(SID=8806F673DEC6B53D9248AF0DD81F6882)
(org.apache.cxf.jaxrs.model.OperationResourceInfoComparatorBase:102) - Both
be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#getDvlById
and
be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#getDvlById
are equal candidates for handling the current request which can lead to
unpredictable results*

Obvious that they are equal candidates because they are the same class. But
what is the cause of this double detection?

Is it because when *JAXRSUtils.**getRootResources*(Message message)  gets
called, I see that it contains 4 entries:

·       (twice) KmopDienstverlenerApiServiceImpl -> my service endpoint

·       io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

·       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService

So twice my service implementation, I wouldn’t know why this is the case?

On my classpath I have set:

·       cxf-rt-rs-service-description-3.5.6.jar                 -> this
handles request for ‘_wadl’

·       cxf-rt-rs-service-description-openapi-v3-3.5.6.jar      -> this
handles request for ‘openapi.[yaml|json]’

·       cxf-rt-rs-service-description-swagger-ui-3.5.6.jar      -> this
handles request for ‘Swagger documentation’

would this be a cause for my service endpoint to appear multiple times?
Aside from that I have no idea what could cause this.

J.P.

-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: donderdag 13 juli 2023 18:24
To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
Subject: Re: How to setup multiple JAXRS server endpoints

Got it, thank you (the Swagger sometimes does surprising things).

Thursday, July 13, 2023, 1:33:07 AM, you wrote:

JPU> The @Parameter annotation seems to be ignored at this level.

JPU> -----Original Message-----

JPU> From: Jean Pierre URKENS <je...@devoteam.com>

JPU> Sent: donderdag 13 juli 2023 7:11

JPU> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'

JPU> <de...@cxf.apache.org>

JPU> Subject: RE: How to setup multiple JAXRS server endpoints

JPU> Yes, SwaggerUI works too!

JPU> I noticed that v2.x of swagger-jaxrs relates to OpenApi v3.1.x

JPU> while my spec is compliant with OpenApi v3.0.x, so I am going to

JPU> stick with v2.1.13 which seems to be that last version for OpenApi
v3.0.x.

JPU> I thought the @Parameter only applied to input parameters ("query",

JPU> "header", "path" or "cookie" parameters), but I'll give it a try.

JPU> J.P.

JPU> -----Original Message-----

JPU> From: Andriy Redko <dr...@gmail.com>

JPU> Sent: woensdag 12 juli 2023 22:16

JPU> To: Jean Pierre URKENS <je...@devoteam.com>;

JPU> dev@cxf.apache.org

JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

JPU> That's awesome, have you got SwaggerUI working as well?

JPU> Yes, you could use 2.2.15 (we already updated to this version, no

JPU> regressions). It seems like the description applies to the whole

JPU> schema (which is the same for both properties), may be you could

JPU> use @Parameter

JPU> instead:

JPU> @Parameter(description="The description I want for prop1")

JPU> Thank you.

JPU> Best Regards,

JPU>     Andriy Redko

>> Hi Andriy,

>> After having migrated everything to "io.swagger.v3.oas.annotations.*"

>> the swagger endpoints for each of my services became active.

>> So far so good, but I do notice that there are discrepancies when

>> annotating models, e.g.:

>>  public class Model1 {

>>   @Schema(description="The description I want for prop1")

>>    private Model2 prop1;

>>   @Schema(description="The description I want for prop2")

>>    private Model2 prop2;

>>   ...

>> }

>> When I generate the openapi.[json|yaml] specification I see that both

>> prop1 and prop2 have a reference to the schema component "Model2"

>> with description ' The description I want for prop2' which is

>> inappropriate for 'prop1'.

>> It is not unlikely to have multiple properties within one Model that

>> are of the same class but are semantically used in a different context.
E.g.

>> something as simple as a ShipmentOrder having two 'Address'

>> properties 'from' and 'to' would result in wrong API documentation.

>> I am aware it has nothing to do with CXF but rather with

>> swagger-jaxrs2-vx.y.z.jar and depending libraries. CXF-3.5.6 has

>> dependency on swagger-jaxrs2-2.1.13.jar. Would it be an issue to

>> replace this dependency with e.g. swagger-jaxrs2-2.2.15.jar (latest

>> stable release according to maven central repo)?

>> J.P.

>> -----Original Message-----

>> From: Jean Pierre URKENS <je...@devoteam.com>

>> Sent: woensdag 12 juli 2023 8:25

>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'

>> <de...@cxf.apache.org>

>> Subject: RE: How to setup multiple JAXRS server endpoints I seem to

>> be mistaken here, the endpoint was loaded (I did a manual HTTP GET

>> test to the endpoint to verify this) although no breakpoints where

>> hit during startup.

>> I am first going to complete the migration to

>> "io.swagger.v3.oas.annotations.*" annotations for all endpoints and

>> then I am going to test again.

>> The application is composed of libraries, some of which use SLF4J but

>> most use LOG4J for logging.

>> J.P.

>> -----Original Message-----

>> From: Andriy Redko <dr...@gmail.com>

>> Sent: woensdag 12 juli 2023 1:13

>> To: Jean Pierre URKENS <je...@devoteam.com>;

>> dev@cxf.apache.org

>> Subject: Re: How to setup multiple JAXRS server endpoints Hi Jean,

>> The

>> OpenApiFeature$Portable#initiliaze(…) should definitely be called

>> (otherwise you shouldn't even see the openapi.json endpoint), so I am

>> not sure why these are not triggering for you.

>>

>> For logging, it seems like you are using SLF4J

>> (org.apache.cxf.common.logging.Slf4jLogger),

>> and also reload4j (aka log4j), why do you need both?

>> Thank you.

>> Best Regards,

>>     Andriy Redko

JPU>>> After some code investigation:



JPU>>> OpenApiFeature implements SwaggerUiSupport and in its

JPU>>> portable#registerSwaggerUiResources(…) method it will call

JPU>>> SwaggerUiSupport#getSwaggerUi(…) which will register the

JPU> SwaggerUiService.



JPU>>> I have put breakpoints on:

JPU>>>    - OpenApiFeature$Portable#initiliaze(…)

JPU>>>    - SwaggerUiService constructor

JPU>>>    - SwaggerUiSupport#getSwaggerUi(…)



JPU>>> but none of them are hit when starting my application?



JPU>>> Although the (spring) logging shows all beans in my

JPU>>> cxf-endpoints.xml have been created?

JPU>>> The *WADL* and *OpenAPI* endpoints to get the specification work.

JPU>>> Even the actual endpoint seems to work although I didn’t hit any

JPU>>> of the breakpoint?



JPU>>> CXF, also doesn’t seem to log a lot, I am hardly getting any log

JPU>>> entries although log level I set to DEBUG.

JPU>>> My logging (except wire message logging) for cxf is setup

JPU>>> correctly (I

JPU>>> think):

JPU>>>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line

JPU>>>    ‘org.apache.cxf.common.logging.Slf4jLogger’

JPU>>>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and

JPU>>>    reload4j-1.2.19.jar are on the classpath

JPU>>>    - the log4j.properties file contains the line:

JPU>>>    ‘log4j.logger.org.apache.cxf=DEBUG’



JPU>>> There are no special instructions mentioned on

JPU>>> https://cxf.apache.org/docs/general-cxf-logging.html so the above

JPU>>> should work (it works for all other packages I use in my
application).



JPU>>> J.P.

JPU>>> *From:* Jean Pierre URKENS <je...@devoteam.com>

JPU>>> *Sent:* dinsdag 11 juli 2023 9:58

JPU>>> *To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <

dev@cxf.apache.org>>>>

JPU>>> *Subject:* RE: How to setup multiple JAXRS server endpoints



JPU>>> Hi Andriy,



JPU>>> As a test I removed all JAX-RS endpoints that use Swagger v2

JPU>>> annotations from my configuration file (see attachment).

JPU>>> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger

JPU>>> v3 annotations, using the OpenApiFeature i.o. Swagger2Feature.

JPU>>> If I run my server with this configuration I only get the

JPU>>> (working)

JPU>>> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint:



JPU>>> So there is some configuration missing to detect/activate the

JPU>>> Swagger endpoint. When I look at the samples that come with the

JPU>>> distribution of CXF (I am using v3.5.6) nothing special seems to

JPU>>> be

JPU> configured to activate this?

JPU>>> Do you have any idea how the SwaggerUiService is picked up when

JPU> loading?



JPU>>> J.P.



JPU>>> -----Original Message-----

JPU>>> From: Andriy Redko <dr...@gmail.com>

JPU>>> Sent: dinsdag 11 juli 2023 3:44

JPU>>> To: Jean Pierre URKENS <je...@devoteam.com>;

JPU>>> dev@cxf.apache.org

JPU>>> Subject: Re: How to setup multiple JAXRS server endpoints



JPU>>> Hi Jean,



JPU>>> I guess you figured one issue, swagger.json -> openapi.json, but

JPU>>> to be honest we have never tested or envisioned the application

JPU>>> that would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same

JPU>>> time, I am afraid this is just not supported. You may get things

JPU>>> back on track when going with OpenAPI 3.0 for all services.



JPU>>> Thank you.



JPU>>> Best Regards,

JPU>>>     Andriy Redko



>>>> Hi Andriy,




>>>> I am trying to trace the difference in handling with another

>>>> application where I’ve got only one CXF service endpoint that uses

>>>> swagger v3 openapi annotations.



>>>> There I see that when handling the Swagger page request (

>>>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json)

>>>> the JAXRSInInterceptor is calling:




>>>> *JAXRSUtils.**getRootResources*(Message message)




>>>> It contains 4 entries:



>>>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint

>>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

>>>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService












>>>> On the application described below with the service ‘oidcsim’ when

>>>> calling the swagger page request

>>>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the

>>>> result of the getRootResources doesn’t contain the

>>>> ClassResourceInfo ‘ SwaggerUiService’. It only contains 3 entries:



>>>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)

>>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource




>>>> The SwaggerUiService is the one that is configured to handle the

JPU>>> ‘api-docs’

>>>> path-request. Since it is missing the request is tried to match

>>>> with the other two resources but fails, hence ‘NOT FOUND’ exception.




>>>> I can’t trace back where these rootResources are set and why the

>>>> SwaggerUiService’ isn’t listed.




>>>> J.P.



>>>> *From:* Jean Pierre URKENS <je...@devoteam.com>

>>>> *Sent:* maandag 10 juli 2023 13:43

>>>> *To:* 'Andriy Redko' <dr...@gmail.com>

>>>> *Subject:* RE: How to setup multiple JAXRS server endpoints




>>>> Andriy,




>>>> I am trying to switch from Swagger v2 to OpenApi v3 annotations

>>>> basically because my starting point is an OpenApi v3.0.7 yaml file

>>>> description and OpenAPI seems to be the way forward.



>>>> For applications where I have only one CXF JAX-RS endpoint exposed

>>>> I had no problems converting. However as soon as there are multiple

>>>> endpoints I run into troubles.




>>>> So, to recall, I've an application exposing 3 JAX-RS endpoints that

>>>> where previously annotated with swagger v2 annotations (i.e.

>>>> package

>>>> io.swagger.annotations.*) which I migrated to



>>>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*).

>>>> In accordance I altered my CXF JAX-RS endpoint configuration from

>>>> (only showing relevant parts, see attachment for full setup):




>>>>                <!-- CXF Swagger2Feature -->



>>>>                <bean id="SwaggerUiConfigOidcApi"

>>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>>>>                               <property name="queryConfigEnabled"



>>>>                               <property name="url"

>>>> value="/op/services/oidcsim/swagger.yaml"/>



>>>>                </bean>



>>>>                <bean id="Swagger2FeatureOidcApi"

>>>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">



>>>>                               <property name="basePath"

>>>> value="/op/services/oidcsim"/>



>>>>                               <property name="usePathBasedConfig"



>>>>                               <property name="resourcePackage"

>>>> value="be.dvtm.aeo.op.oidc"/>



>>>>                               <property name="supportSwaggerUi"



>>>>                               <property name="swaggerUiConfig"

>>>> ref="SwaggerUiConfigOidcApi"/>



>>>>                </bean>



>>>>                <jaxrs:server id="OidcProviderApiServer"

>>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>>>>                               ....



>>>>                               <jaxrs:features>



>>>>                                              <ref

>>>> bean="Swagger2FeatureOidcApi" />



>>>>                               </jaxrs:features>



>>>>                               ...



>>>>                </jaxrs:server>




>>>> TO:



>>>>                <!-- CXF OpenAPIFeature -->



>>>>                <bean id="OidcSwaggerUiConfig"

>>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>>>>                               <property name="queryConfigEnabled"



>>>>                               <property name="url"

>>>> value="openapi.json"/>



>>>>                </bean>



>>>>                <bean id="OidcOpenApiFeature"

>>>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">



>>>>                               <property name="supportSwaggerUi"



>>>>                               <property name="swaggerUiConfig"

>>>> ref="OidcSwaggerUiConfig"/>



>>>>                               <property name="swaggerUiVersion"



>>>>                               <property name="scan" value="false"/>



>>>>                               <property name="useContextBasedConfig"



>>>>                               <property name="resourcePackages"

>>>> value="be.dvtm.aeo.op.oidc"/>



>>>>                </bean>



>>>>                <jaxrs:server id="OidcProviderApiServer"

>>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>>>>                               ....



>>>>                               <jaxrs:features>



>>>>                                              <ref

JPU>>> bean="OidcOpenApiFeature"



>>>>                               </jaxrs:features>



>>>>                               ...



>>>>                </jaxrs:server>








>>>> Now when starting my application and navigating to the root part "

>>>> http://localhost:localPort/op/services" I get an overview of all my

>>>> endpoints:




>>>> Now there are 3 RESTful service endpoints setup:



>>>>    1. ‘oidcsim’ which I switched to swagger v3 annotations

>>>>    2. ‘openapi’ currently still swagger v2 annotations

>>>>    3. ‘sdx’ currently still swagger v2 annotations




>>>> all endpoints work except for the ‘swagger endpoint address for the

>>>> oidcsim

>>>> endpoint:

>>>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services

>>>> /o

>>>> i

>>>> dcsim/swagger.json



>>>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*

>>>> endpoint of the oidcsim resource. I am getting an error (the value

>>>> of the ‘url’ query parameter isn’t relevant):




>>>>         “WebApplicationException has been caught, status: 404,

>>>> message: HTTP 404 Not Found”




>>>> When I try (without the ‘/oidcsim’ context):

>>>> http://l-p53-008:8081/op/services/api-docs I get:



>>>>                “No service was found.”




>>>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs

>>>> doesn’t exist, where as the endpoint

>>>> http://l-p53-008:8081/op/services/api-docs does exist but no

>>>> service

JPU>>> description is found?



>>>> Of course my intention is to get working, as previously with the

>>>> swagger v2 setup for which I then specifically added the

>>>> *Swagger2Feature* config

>>>> parameters:



>>>>                               <property name="basePath"

>>>> value="/op/services/oidcsim"/>



>>>>                               <property name="usePathBasedConfig"




>>>> But I don’t find the according configuration options for the

>>>> *OpenApiFeature* class or whether I should configure this in

>>>> another way.




>>>> Any suggestions on this?




>>>> Regards,




>>>> J.P.








>>>> -----Original Message-----

>>>> From: Andriy Redko <dr...@gmail.com>

>>>> Sent: donderdag 25 mei 2023 2:27

>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>>> dev@cxf.apache.org

>>>> Subject: Re: How to setup multiple JAXRS server endpoints




>>>> Hi Jean,




>>>> You may run into Swagger JAX-RS scanner limitations, as far as I

>>>> can tell - it checks class annotations for SwaggerDefinition, does

>>>> not traverse the hierarchy [1].




>>>> [1]

>>>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagge

>>>> r-

>>>> j

>>>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194




>>>> Best Regards,



>>>>     Andriy Redko




>>>>>  RE: How to setup multiple JAXRS server endpoints




>>>>> Still one question );




>>>>> The generated swagger file doesn’t take into account the



>>>>> @SwaggerDefintion on my interface classes?




>>>>> As a test I looked at



>>>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m

>>>>> a



>>>>> in/release/samples/jax_rs/description_swagger2_web**



>>>>> and** modified** sample2*



>>>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m

>>>>> a



>>>>> in/release/samples/jax_rs/description_swagger2_web



>>>>> and modified sample2> as follows:




>>>>>    @Path("/sample2")




>>>>>       @Api(value = "/sample2",authorizations=



>>>>>       {@Authorization(value="bearer")},description = "Sample2

>>>> (modified) JAX-RS



>>>>>       service with Swagger documentation")




>>>>>       @SwaggerDefinition(




>>>>>               info = @Info(




>>>>>                       description = "Sample2 server",




>>>>>                       version="1.0",




>>>>>                       title = "Test2",




>>>>>                       contact = @Contact(name = "J.P. Urkens",email =
"



>>>>>       *jean-pierre.urkens@devoteam.com* <

>>>> jean-pierre.urkens@devoteam.com>



>>>>>       ")),




>>>>>               securityDefinition =



>>>>>       @SecurityDefinition(apiKeyAuthDefinitions=



>>>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name=
<*%7B@ApiKeyAuthDefinition(key=>

>>>> "A

>>>> u

>>>> thorization",description="Use*



>>>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer



>>>>>       &lt;accessToken&gt;'")})




>>>>>       )




>>>>>       public class Sample2 {...}




>>>>> This correctly generates the ‘securityDefintions’ in the swagger file.




>>>>> If include the same @SwaggerDefinition and the authorizations on



>>>>> the @Api annotation as above in my interface classes then the



>>>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?




>>>>> Any idea what I might be missing?




>>>>> Regards,




>>>>> J.P.




>>>>> -----Original Message-----



>>>>> From: Jean Pierre URKENS <je...@devoteam.com>



>>>>> Sent: dinsdag 23 mei 2023 12:52



>>>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <



>>>>> Subject: RE: How to setup multiple JAXRS server endpoints




>>>>> Hi Andriy,




>>>>> I added the parameter usePathBasedConfig=true to the



>>>>> Swagger2Feature bean declarations but still it does generate an



>>>>> empty swagger.yaml for interfaces KmopResources and



>>>>> KmopDienstverlener although I noticed that for these interfaces

>>>>> the



>>>>> @Path() annotation was commented out (as I included it in the



>>>>> server declaration). After providing an empty @Path("")

>>>>> declaration on

>>>> the API interface classes everything worked.




>>>>> Thanks for the support.




>>>>> -----Original Message-----




>>>>> From: Andriy Redko <dr...@gmail.com>




>>>>> Sent: dinsdag 23 mei 2023 3:42




>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;



>>>>> dev@cxf.apache.org




>>>>> Subject: Re: How to setup multiple JAXRS server endpoints




>>>>> Hi Jean,




>>>>> The main problem to configure Swagger property in your particular



>>>>> case is that the server address is not "known" or "introspectable"

>>>>> for

>>>> Swagger.



>>>>> Intuitively, it has to be set manually using basePath to the,



>>>>> essentially, the server address




>>>>> part:




>>>>>  - /op/services/accounts




>>>>>  - /op/services/resources




>>>>>  - /op/services/dienstverlener




>>>>> You could read more about other Swagger properties you have asked
here:



>>>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Int

>>>>> e



>>>>> gration-and-Configuration#configuration-properties




>>>>> You definitely need to set usePathBasedConfig to "true" otherwise



>>>>> you will see the same Swagger specs for all servers. We have a



>>>>> sample here which uses 2 jaxrs:server




>>>>> instances:



>>>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma

>>>>> i



>>>>> n/release/samples/jax_rs/description_swagger2_web




>>>>> Regarding SwaggerUI, I think the value for each of those should be



>>>>> set to,



>>>>> respectively:




>>>>>  - /op/services/accounts/swagger.yaml




>>>>>  - /op/services/resources/swagger.yaml




>>>>>  - /op/services/dienstverlener/swagger.yaml




>>>>> I believe this is matching your settings already, except the



>>>>> usePathBasedConfig part. The example referred above could be



>>>>> helpful, my apologies if I missed something, there are quite a lot



>>>>> of questions :-) The fact that the generated Swagger specification



>>>>> is empty is unexpected - it should not happen when JAX-RS

>>>>> resources

>>>> are properly configured.




>>>>> Thank you.




>>>>> Best Regards,




>>>>>     Andriy Redko




>>>>>>  RE: How to setup multiple JAXRS server endpoints




>>>>>> Hi Andriy,




>>>>>> I am not quite understanding how to correctly configure the



>>>>> Swagger2Feature.




>>>>>> Referring to the attached cxf-endpoints configuration I (as a



>>>>>> test)




>>>>>> created




>>>>>> 3 JAXRS server instances:




>>>>>> 1.      A* KmopApiServer* server for the*




>>>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving




>>>>>> requests for URI path:




>>>>>>        * <protocol>**//<host:<port>/op/services/accounts*




>>>>>>    ‘op’  = root path of the web application




>>>>>>             ‘services’ = servlet path of the CXF-servlet




>>>>>>       The address of the server is set to ‘/accounts’ and the



>>>>>> @Path(…)




>>>>>>       annotation on the interface class was cleared.




>>>>>> 2.      A* Kmop**Resources**ApiServer* server for the*

>>>> be.dvtm.aeo.op.*




>>>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving




>>>>>> requests for URI path:




>>>>>>        * <protocol>**//<host:<port>/op/services/**resources*




>>>>>> The address of the server is set to ‘/resources’ and the @Path(…)




>>>>>> annotation on the interface class was cleared.




>>>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*



>>>>> be.dvtm.aeo.op.*




>>>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving




>>>>>> requests for URI path:




>>>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*




>>>>>> The address of the server is set to ‘/dienstverlener’ and the




>>>>>> @Path(…) annotation on the interface class was cleared.




>>>>>> For each of these server instances I’ve set the Swagger2Feature




>>>>>> with configuration as indicated in the attached cxf-endpoints.xml.




>>>>>> With regard to the configurations for the Swagger2Feature I’ve

>>>>>> the




>>>>>> following questions:




>>>>>> a)      Referring to *

>>>> https://cxf.apache.org/docs/swagger2feature.html*




>>>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you




>>>>>> clarify on the following configuration parameters:




>>>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘




>>>>>> /op/services’) or to the JAX-RS server instance (e.g.




>>>>>> ‘/op/services/accounts’) or still something else? Is it used to




>>>>>> resolve service classes or is it just for documentation in the



>>>>>> swagger



>>>>> file?




>>>>>> *ii.    ** resourcePackage* – the description mentions ‘package
names’




>>>>>> while the default mentions ‘service classes’? Service 2 and 3



>>>>>> above




>>>>>> are within the same package (generated from the same yaml




>>>>>> specification that included both interfaces).




>>>>>> *iii.   ** ig**noreRoutes* – is this taken into account when




>>>>>> scanAllResources=false?




>>>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter

>>>> value




>>>>>> (cf. question ‘a’)?




>>>>>> b)      What would be the correct URL to generate a swagger.yaml

>>>>>> file



>>>>> for




>>>>>> each of the above interfaces? Initially I called:




>>>>>> *i.     **



>>>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*




>>>>>> *ii.    **



>>>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*




>>>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*




>>>>>> *lener/swagger.yaml*




>>>>>>    All three requests delivered the same yaml specification,



>>>>>> namely



>>>>> the one




>>>>>>       for interface* KmopApiServer*?




>>>>>> c)      I tried to debug the processing of the requests under ‘b)’

>>>>>> and



>>>>> this




>>>>>> is done by the class JAXRSInterceptor#processRequest where the




>>>>>> MessageImpl object for request “ii.” looks like the one attached.




>>>>>> It finds 3 resource




>>>>>> classes:




>>>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl




>>>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource




>>>>>>       org.apache

Re: Request mapping warnings

Posted by Andrey Redko <dr...@gmail.com>.
Hi Jean,

Do you use CXF Spring Boot autoconfiguration [1]? If yes, it has a few
controls over scans [1], either beans or classes (I am off this week so
cannot look into the configuration). Thank you.

[1] https://cxf.apache.org/docs/springboot.html

Best Regards,
    Andriy Redko

On Thu, Jul 20, 2023, 2:23 AM Jean Pierre URKENS <
jean-pierre.urkens@devoteam.com> wrote:

> Hi all,
>
>
>
> As a test I removed the @org.springframework.stereotype.Service(“
> *KmopDienstverlenerApi*”) annotation on my service implementation class.
> So no @Service annotations further exist. Still when checking the return of
> *JAXRSUtils.**getRootResources*(Message message) via breakpoint I
>
> Still notice that my service classes are listed twice in the return result
> *List<ClassResourceInfo>*.
>
>
>
> The only annotations I’ve left in my code are:
>
>    - standard JAX-RS annotations:
>    javax.ws.rs.[GET|POST|Consumes|Produces|HeaderParam|PathParam|QueryParam|Path|core.MediaType|core.Response]
>    - io.swagger.v3.oas.annotations.*
>
> I suppose none of these would be responsible for an extra registration of
> my service classes.
>
>
>
> So the only point where service registration occurs is in the bean
> declaration file cxf-endpoint.xml, see attachment. The only thing I can
> think of a possible double registration in this file is the declaration of
> the OpenApiFeature (e.g. <bean id=”*KmopOpenApiFeature*” …> ) for each
> resource endpoint in addition to the <jaxrs:server /> declaration using
> this OpenApiFeature.
>
> But I would assume that configuring the OpenApiFeature, through a bean
> declaration, wouldn’t register a service.
>
>
>
> The ‘imported’ resources context-v2.xml and onderneming-context.xml define
> some <jaxws:client/> instances that have nothing to do with these JAX-WS/RS
> endpoints declared in this file.
>
>
>
> Is there something I can trace into to see when a service gets registered
> as a *ClassResourceInfo *?
>
>
>
> Regards,
>
>
>
> J.P. Urkens
>
> *From:* Andrey Redko <dr...@gmail.com>
> *Sent:* woensdag 19 juli 2023 19:30
> *To:* Jean Pierre URKENS <je...@devoteam.com>
> *Cc:* Daniel Kulp <de...@cxf.apache.org>
> *Subject:* Re: Request mapping warnings
>
>
>
> Hi Jean,
>
>
>
> Indeed it looks like you have the same resource registered twice hence the
> warning. It may come from the use of automatic resource scans and manual
> resource registration.
>
> Best Regards,
>     Andriy Redko
>
>
>
> On Wed, Jul 19, 2023, 7:39 AM Jean Pierre URKENS <
> jean-pierre.urkens@devoteam.com> wrote:
>
> Still some minor issue related to request mapping.
>
> I notice I am getting warnings like:
>
> *2023-07-19 13:08:23,022 [T8N1TP1-4] WARN
> (SID=8806F673DEC6B53D9248AF0DD81F6882)
> (org.apache.cxf.jaxrs.model.OperationResourceInfoComparatorBase:102) - Both
> be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#getDvlById
> and
> be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#getDvlById
> are equal candidates for handling the current request which can lead to
> unpredictable results*
>
> Obvious that they are equal candidates because they are the same class.
> But what is the cause of this double detection?
>
> Is it because when *JAXRSUtils.**getRootResources*(Message message)  gets
> called, I see that it contains 4 entries:
>
> ·       (twice) KmopDienstverlenerApiServiceImpl -> my service endpoint
>
> ·       io.swagger.v3.jaxrs2.integration.resources.OpenApiResource
>
> ·       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService
>
> So twice my service implementation, I wouldn’t know why this is the case?
>
> On my classpath I have set:
>
> ·       cxf-rt-rs-service-description-3.5.6.jar                 -> this
> handles request for ‘_wadl’
>
> ·       cxf-rt-rs-service-description-openapi-v3-3.5.6.jar      -> this
> handles request for ‘openapi.[yaml|json]’
>
> ·       cxf-rt-rs-service-description-swagger-ui-3.5.6.jar      -> this
> handles request for ‘Swagger documentation’
>
> would this be a cause for my service endpoint to appear multiple times?
> Aside from that I have no idea what could cause this.
>
> J.P.
>
> -----Original Message-----
> From: Andriy Redko <dr...@gmail.com>
> Sent: donderdag 13 juli 2023 18:24
> To: Jean Pierre URKENS <je...@devoteam.com>;
> dev@cxf.apache.org
> Subject: Re: How to setup multiple JAXRS server endpoints
>
> Got it, thank you (the Swagger sometimes does surprising things).
>
> Thursday, July 13, 2023, 1:33:07 AM, you wrote:
>
> JPU> The @Parameter annotation seems to be ignored at this level.
>
> JPU> -----Original Message-----
>
> JPU> From: Jean Pierre URKENS <je...@devoteam.com>
>
> JPU> Sent: donderdag 13 juli 2023 7:11
>
> JPU> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'
>
> JPU> <de...@cxf.apache.org>
>
> JPU> Subject: RE: How to setup multiple JAXRS server endpoints
>
> JPU> Yes, SwaggerUI works too!
>
> JPU> I noticed that v2.x of swagger-jaxrs relates to OpenApi v3.1.x
>
> JPU> while my spec is compliant with OpenApi v3.0.x, so I am going to
>
> JPU> stick with v2.1.13 which seems to be that last version for OpenApi
> v3.0.x.
>
> JPU> I thought the @Parameter only applied to input parameters ("query",
>
> JPU> "header", "path" or "cookie" parameters), but I'll give it a try.
>
> JPU> J.P.
>
> JPU> -----Original Message-----
>
> JPU> From: Andriy Redko <dr...@gmail.com>
>
> JPU> Sent: woensdag 12 juli 2023 22:16
>
> JPU> To: Jean Pierre URKENS <je...@devoteam.com>;
>
> JPU> dev@cxf.apache.org
>
> JPU> Subject: Re: How to setup multiple JAXRS server endpoints
>
> JPU> Hi Jean,
>
> JPU> That's awesome, have you got SwaggerUI working as well?
>
> JPU> Yes, you could use 2.2.15 (we already updated to this version, no
>
> JPU> regressions). It seems like the description applies to the whole
>
> JPU> schema (which is the same for both properties), may be you could
>
> JPU> use @Parameter
>
> JPU> instead:
>
> JPU> @Parameter(description="The description I want for prop1")
>
> JPU> Thank you.
>
> JPU> Best Regards,
>
> JPU>     Andriy Redko
>
> >> Hi Andriy,
>
> >> After having migrated everything to "io.swagger.v3.oas.annotations.*"
>
> >> the swagger endpoints for each of my services became active.
>
> >> So far so good, but I do notice that there are discrepancies when
>
> >> annotating models, e.g.:
>
> >>  public class Model1 {
>
> >>   @Schema(description="The description I want for prop1")
>
> >>    private Model2 prop1;
>
> >>   @Schema(description="The description I want for prop2")
>
> >>    private Model2 prop2;
>
> >>   ...
>
> >> }
>
> >> When I generate the openapi.[json|yaml] specification I see that both
>
> >> prop1 and prop2 have a reference to the schema component "Model2"
>
> >> with description ' The description I want for prop2' which is
>
> >> inappropriate for 'prop1'.
>
> >> It is not unlikely to have multiple properties within one Model that
>
> >> are of the same class but are semantically used in a different context.
> E.g.
>
> >> something as simple as a ShipmentOrder having two 'Address'
>
> >> properties 'from' and 'to' would result in wrong API documentation.
>
> >> I am aware it has nothing to do with CXF but rather with
>
> >> swagger-jaxrs2-vx.y.z.jar and depending libraries. CXF-3.5.6 has
>
> >> dependency on swagger-jaxrs2-2.1.13.jar. Would it be an issue to
>
> >> replace this dependency with e.g. swagger-jaxrs2-2.2.15.jar (latest
>
> >> stable release according to maven central repo)?
>
> >> J.P.
>
> >> -----Original Message-----
>
> >> From: Jean Pierre URKENS <je...@devoteam.com>
>
> >> Sent: woensdag 12 juli 2023 8:25
>
> >> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'
>
> >> <de...@cxf.apache.org>
>
> >> Subject: RE: How to setup multiple JAXRS server endpoints I seem to
>
> >> be mistaken here, the endpoint was loaded (I did a manual HTTP GET
>
> >> test to the endpoint to verify this) although no breakpoints where
>
> >> hit during startup.
>
> >> I am first going to complete the migration to
>
> >> "io.swagger.v3.oas.annotations.*" annotations for all endpoints and
>
> >> then I am going to test again.
>
> >> The application is composed of libraries, some of which use SLF4J but
>
> >> most use LOG4J for logging.
>
> >> J.P.
>
> >> -----Original Message-----
>
> >> From: Andriy Redko <dr...@gmail.com>
>
> >> Sent: woensdag 12 juli 2023 1:13
>
> >> To: Jean Pierre URKENS <je...@devoteam.com>;
>
> >> dev@cxf.apache.org
>
> >> Subject: Re: How to setup multiple JAXRS server endpoints Hi Jean,
>
> >> The
>
> >> OpenApiFeature$Portable#initiliaze(…) should definitely be called
>
> >> (otherwise you shouldn't even see the openapi.json endpoint), so I am
>
> >> not sure why these are not triggering for you.
>
> >>
>
> >> For logging, it seems like you are using SLF4J
>
> >> (org.apache.cxf.common.logging.Slf4jLogger),
>
> >> and also reload4j (aka log4j), why do you need both?
>
> >> Thank you.
>
> >> Best Regards,
>
> >>     Andriy Redko
>
> JPU>>> After some code investigation:
>
>
>
> JPU>>> OpenApiFeature implements SwaggerUiSupport and in its
>
> JPU>>> portable#registerSwaggerUiResources(…) method it will call
>
> JPU>>> SwaggerUiSupport#getSwaggerUi(…) which will register the
>
> JPU> SwaggerUiService.
>
>
>
> JPU>>> I have put breakpoints on:
>
> JPU>>>    - OpenApiFeature$Portable#initiliaze(…)
>
> JPU>>>    - SwaggerUiService constructor
>
> JPU>>>    - SwaggerUiSupport#getSwaggerUi(…)
>
>
>
> JPU>>> but none of them are hit when starting my application?
>
>
>
> JPU>>> Although the (spring) logging shows all beans in my
>
> JPU>>> cxf-endpoints.xml have been created?
>
> JPU>>> The *WADL* and *OpenAPI* endpoints to get the specification work.
>
> JPU>>> Even the actual endpoint seems to work although I didn’t hit any
>
> JPU>>> of the breakpoint?
>
>
>
> JPU>>> CXF, also doesn’t seem to log a lot, I am hardly getting any log
>
> JPU>>> entries although log level I set to DEBUG.
>
> JPU>>> My logging (except wire message logging) for cxf is setup
>
> JPU>>> correctly (I
>
> JPU>>> think):
>
> JPU>>>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line
>
> JPU>>>    ‘org.apache.cxf.common.logging.Slf4jLogger’
>
> JPU>>>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and
>
> JPU>>>    reload4j-1.2.19.jar are on the classpath
>
> JPU>>>    - the log4j.properties file contains the line:
>
> JPU>>>    ‘log4j.logger.org.apache.cxf=DEBUG’
>
>
>
> JPU>>> There are no special instructions mentioned on
>
> JPU>>> https://cxf.apache.org/docs/general-cxf-logging.html so the above
>
> JPU>>> should work (it works for all other packages I use in my
> application).
>
>
>
> JPU>>> J.P.
>
> JPU>>> *From:* Jean Pierre URKENS <je...@devoteam.com>
>
> JPU>>> *Sent:* dinsdag 11 juli 2023 9:58
>
> JPU>>> *To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <
>
> dev@cxf.apache.org>>>>
>
> JPU>>> *Subject:* RE: How to setup multiple JAXRS server endpoints
>
>
>
> JPU>>> Hi Andriy,
>
>
>
> JPU>>> As a test I removed all JAX-RS endpoints that use Swagger v2
>
> JPU>>> annotations from my configuration file (see attachment).
>
> JPU>>> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger
>
> JPU>>> v3 annotations, using the OpenApiFeature i.o. Swagger2Feature.
>
> JPU>>> If I run my server with this configuration I only get the
>
> JPU>>> (working)
>
> JPU>>> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint:
>
>
>
> JPU>>> So there is some configuration missing to detect/activate the
>
> JPU>>> Swagger endpoint. When I look at the samples that come with the
>
> JPU>>> distribution of CXF (I am using v3.5.6) nothing special seems to
>
> JPU>>> be
>
> JPU> configured to activate this?
>
> JPU>>> Do you have any idea how the SwaggerUiService is picked up when
>
> JPU> loading?
>
>
>
> JPU>>> J.P.
>
>
>
> JPU>>> -----Original Message-----
>
> JPU>>> From: Andriy Redko <dr...@gmail.com>
>
> JPU>>> Sent: dinsdag 11 juli 2023 3:44
>
> JPU>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>
> JPU>>> dev@cxf.apache.org
>
> JPU>>> Subject: Re: How to setup multiple JAXRS server endpoints
>
>
>
> JPU>>> Hi Jean,
>
>
>
> JPU>>> I guess you figured one issue, swagger.json -> openapi.json, but
>
> JPU>>> to be honest we have never tested or envisioned the application
>
> JPU>>> that would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same
>
> JPU>>> time, I am afraid this is just not supported. You may get things
>
> JPU>>> back on track when going with OpenAPI 3.0 for all services.
>
>
>
> JPU>>> Thank you.
>
>
>
> JPU>>> Best Regards,
>
> JPU>>>     Andriy Redko
>
>
>
> >>>> Hi Andriy,
>
>
>
>
>
> >>>> I am trying to trace the difference in handling with another
>
> >>>> application where I’ve got only one CXF service endpoint that uses
>
> >>>> swagger v3 openapi annotations.
>
>
>
> >>>> There I see that when handling the Swagger page request (
>
> >>>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json)
>
> >>>> the JAXRSInInterceptor is calling:
>
>
>
>
>
> >>>> *JAXRSUtils.**getRootResources*(Message message)
>
>
>
>
>
> >>>> It contains 4 entries:
>
>
>
> >>>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint
>
> >>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource
>
> >>>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService
>
>
>
>
>
>
>
>
>
>
>
>
>
> >>>> On the application described below with the service ‘oidcsim’ when
>
> >>>> calling the swagger page request
>
> >>>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the
>
> >>>> result of the getRootResources doesn’t contain the
>
> >>>> ClassResourceInfo ‘ SwaggerUiService’. It only contains 3 entries:
>
>
>
> >>>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)
>
> >>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource
>
>
>
>
>
> >>>> The SwaggerUiService is the one that is configured to handle the
>
> JPU>>> ‘api-docs’
>
> >>>> path-request. Since it is missing the request is tried to match
>
> >>>> with the other two resources but fails, hence ‘NOT FOUND’ exception.
>
>
>
>
>
> >>>> I can’t trace back where these rootResources are set and why the
>
> >>>> SwaggerUiService’ isn’t listed.
>
>
>
>
>
> >>>> J.P.
>
>
>
> >>>> *From:* Jean Pierre URKENS <je...@devoteam.com>
>
> >>>> *Sent:* maandag 10 juli 2023 13:43
>
> >>>> *To:* 'Andriy Redko' <dr...@gmail.com>
>
> >>>> *Subject:* RE: How to setup multiple JAXRS server endpoints
>
>
>
>
>
> >>>> Andriy,
>
>
>
>
>
> >>>> I am trying to switch from Swagger v2 to OpenApi v3 annotations
>
> >>>> basically because my starting point is an OpenApi v3.0.7 yaml file
>
> >>>> description and OpenAPI seems to be the way forward.
>
>
>
> >>>> For applications where I have only one CXF JAX-RS endpoint exposed
>
> >>>> I had no problems converting. However as soon as there are multiple
>
> >>>> endpoints I run into troubles.
>
>
>
>
>
> >>>> So, to recall, I've an application exposing 3 JAX-RS endpoints that
>
> >>>> where previously annotated with swagger v2 annotations (i.e.
>
> >>>> package
>
> >>>> io.swagger.annotations.*) which I migrated to
>
>
>
> >>>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*).
>
> >>>> In accordance I altered my CXF JAX-RS endpoint configuration from
>
> >>>> (only showing relevant parts, see attachment for full setup):
>
>
>
>
>
> >>>>                <!-- CXF Swagger2Feature -->
>
>
>
> >>>>                <bean id="SwaggerUiConfigOidcApi"
>
> >>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">
>
>
>
> >>>>                               <property name="queryConfigEnabled"
>
>
>
> >>>>                               <property name="url"
>
> >>>> value="/op/services/oidcsim/swagger.yaml"/>
>
>
>
> >>>>                </bean>
>
>
>
> >>>>                <bean id="Swagger2FeatureOidcApi"
>
> >>>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">
>
>
>
> >>>>                               <property name="basePath"
>
> >>>> value="/op/services/oidcsim"/>
>
>
>
> >>>>                               <property name="usePathBasedConfig"
>
>
>
> >>>>                               <property name="resourcePackage"
>
> >>>> value="be.dvtm.aeo.op.oidc"/>
>
>
>
> >>>>                               <property name="supportSwaggerUi"
>
>
>
> >>>>                               <property name="swaggerUiConfig"
>
> >>>> ref="SwaggerUiConfigOidcApi"/>
>
>
>
> >>>>                </bean>
>
>
>
> >>>>                <jaxrs:server id="OidcProviderApiServer"
>
> >>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">
>
>
>
> >>>>                               ....
>
>
>
> >>>>                               <jaxrs:features>
>
>
>
> >>>>                                              <ref
>
> >>>> bean="Swagger2FeatureOidcApi" />
>
>
>
> >>>>                               </jaxrs:features>
>
>
>
> >>>>                               ...
>
>
>
> >>>>                </jaxrs:server>
>
>
>
>
>
> >>>> TO:
>
>
>
> >>>>                <!-- CXF OpenAPIFeature -->
>
>
>
> >>>>                <bean id="OidcSwaggerUiConfig"
>
> >>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">
>
>
>
> >>>>                               <property name="queryConfigEnabled"
>
>
>
> >>>>                               <property name="url"
>
> >>>> value="openapi.json"/>
>
>
>
> >>>>                </bean>
>
>
>
> >>>>                <bean id="OidcOpenApiFeature"
>
> >>>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">
>
>
>
> >>>>                               <property name="supportSwaggerUi"
>
>
>
> >>>>                               <property name="swaggerUiConfig"
>
> >>>> ref="OidcSwaggerUiConfig"/>
>
>
>
> >>>>                               <property name="swaggerUiVersion"
>
>
>
> >>>>                               <property name="scan" value="false"/>
>
>
>
> >>>>                               <property name="useContextBasedConfig"
>
>
>
> >>>>                               <property name="resourcePackages"
>
> >>>> value="be.dvtm.aeo.op.oidc"/>
>
>
>
> >>>>                </bean>
>
>
>
> >>>>                <jaxrs:server id="OidcProviderApiServer"
>
> >>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">
>
>
>
> >>>>                               ....
>
>
>
> >>>>                               <jaxrs:features>
>
>
>
> >>>>                                              <ref
>
> JPU>>> bean="OidcOpenApiFeature"
>
>
>
> >>>>                               </jaxrs:features>
>
>
>
> >>>>                               ...
>
>
>
> >>>>                </jaxrs:server>
>
>
>
>
>
>
>
>
>
> >>>> Now when starting my application and navigating to the root part "
>
> >>>> http://localhost:localPort/op/services" I get an overview of all my
>
> >>>> endpoints:
>
>
>
>
>
> >>>> Now there are 3 RESTful service endpoints setup:
>
>
>
> >>>>    1. ‘oidcsim’ which I switched to swagger v3 annotations
>
> >>>>    2. ‘openapi’ currently still swagger v2 annotations
>
> >>>>    3. ‘sdx’ currently still swagger v2 annotations
>
>
>
>
>
> >>>> all endpoints work except for the ‘swagger endpoint address for the
>
> >>>> oidcsim
>
> >>>> endpoint:
>
> >>>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services
>
> >>>> /o
>
> >>>> i
>
> >>>> dcsim/swagger.json
>
>
>
> >>>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*
>
> >>>> endpoint of the oidcsim resource. I am getting an error (the value
>
> >>>> of the ‘url’ query parameter isn’t relevant):
>
>
>
>
>
> >>>>         “WebApplicationException has been caught, status: 404,
>
> >>>> message: HTTP 404 Not Found”
>
>
>
>
>
> >>>> When I try (without the ‘/oidcsim’ context):
>
> >>>> http://l-p53-008:8081/op/services/api-docs I get:
>
>
>
> >>>>                “No service was found.”
>
>
>
>
>
> >>>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs
>
> >>>> doesn’t exist, where as the endpoint
>
> >>>> http://l-p53-008:8081/op/services/api-docs does exist but no
>
> >>>> service
>
> JPU>>> description is found?
>
>
>
> >>>> Of course my intention is to get working, as previously with the
>
> >>>> swagger v2 setup for which I then specifically added the
>
> >>>> *Swagger2Feature* config
>
> >>>> parameters:
>
>
>
> >>>>                               <property name="basePath"
>
> >>>> value="/op/services/oidcsim"/>
>
>
>
> >>>>                               <property name="usePathBasedConfig"
>
>
>
>
>
> >>>> But I don’t find the according configuration options for the
>
> >>>> *OpenApiFeature* class or whether I should configure this in
>
> >>>> another way.
>
>
>
>
>
> >>>> Any suggestions on this?
>
>
>
>
>
> >>>> Regards,
>
>
>
>
>
> >>>> J.P.
>
>
>
>
>
>
>
>
>
> >>>> -----Original Message-----
>
> >>>> From: Andriy Redko <dr...@gmail.com>
>
> >>>> Sent: donderdag 25 mei 2023 2:27
>
> >>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>
> >>>> dev@cxf.apache.org
>
> >>>> Subject: Re: How to setup multiple JAXRS server endpoints
>
>
>
>
>
> >>>> Hi Jean,
>
>
>
>
>
> >>>> You may run into Swagger JAX-RS scanner limitations, as far as I
>
> >>>> can tell - it checks class annotations for SwaggerDefinition, does
>
> >>>> not traverse the hierarchy [1].
>
>
>
>
>
> >>>> [1]
>
> >>>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagge
>
> >>>> r-
>
> >>>> j
>
> >>>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194
>
>
>
>
>
> >>>> Best Regards,
>
>
>
> >>>>     Andriy Redko
>
>
>
>
>
> >>>>>  RE: How to setup multiple JAXRS server endpoints
>
>
>
>
>
> >>>>> Still one question );
>
>
>
>
>
> >>>>> The generated swagger file doesn’t take into account the
>
>
>
> >>>>> @SwaggerDefintion on my interface classes?
>
>
>
>
>
> >>>>> As a test I looked at
>
>
>
> >>>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m
>
> >>>>> a
>
>
>
> >>>>> in/release/samples/jax_rs/description_swagger2_web**
>
>
>
> >>>>> and** modified** sample2*
>
>
>
> >>>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m
>
> >>>>> a
>
>
>
> >>>>> in/release/samples/jax_rs/description_swagger2_web
>
>
>
> >>>>> and modified sample2> as follows:
>
>
>
>
>
> >>>>>    @Path("/sample2")
>
>
>
>
>
> >>>>>       @Api(value = "/sample2",authorizations=
>
>
>
> >>>>>       {@Authorization(value="bearer")},description = "Sample2
>
> >>>> (modified) JAX-RS
>
>
>
> >>>>>       service with Swagger documentation")
>
>
>
>
>
> >>>>>       @SwaggerDefinition(
>
>
>
>
>
> >>>>>               info = @Info(
>
>
>
>
>
> >>>>>                       description = "Sample2 server",
>
>
>
>
>
> >>>>>                       version="1.0",
>
>
>
>
>
> >>>>>                       title = "Test2",
>
>
>
>
>
> >>>>>                       contact = @Contact(name = "J.P. Urkens",email
> = "
>
>
>
> >>>>>       *jean-pierre.urkens@devoteam.com* <
>
> >>>> jean-pierre.urkens@devoteam.com>
>
>
>
> >>>>>       ")),
>
>
>
>
>
> >>>>>               securityDefinition =
>
>
>
> >>>>>       @SecurityDefinition(apiKeyAuthDefinitions=
>
>
>
> >>>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name=
> <*%7B@ApiKeyAuthDefinition(key=>
>
> >>>> "A
>
> >>>> u
>
> >>>> thorization",description="Use*
>
>
>
> >>>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer
>
>
>
> >>>>>       &lt;accessToken&gt;'")})
>
>
>
>
>
> >>>>>       )
>
>
>
>
>
> >>>>>       public class Sample2 {...}
>
>
>
>
>
> >>>>> This correctly generates the ‘securityDefintions’ in the swagger
> file.
>
>
>
>
>
> >>>>> If include the same @SwaggerDefinition and the authorizations on
>
>
>
> >>>>> the @Api annotation as above in my interface classes then the
>
>
>
> >>>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?
>
>
>
>
>
> >>>>> Any idea what I might be missing?
>
>
>
>
>
> >>>>> Regards,
>
>
>
>
>
> >>>>> J.P.
>
>
>
>
>
> >>>>> -----Original Message-----
>
>
>
> >>>>> From: Jean Pierre URKENS <je...@devoteam.com>
>
>
>
> >>>>> Sent: dinsdag 23 mei 2023 12:52
>
>
>
> >>>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <
>
>
>
> >>>>> Subject: RE: How to setup multiple JAXRS server endpoints
>
>
>
>
>
> >>>>> Hi Andriy,
>
>
>
>
>
> >>>>> I added the parameter usePathBasedConfig=true to the
>
>
>
> >>>>> Swagger2Feature bean declarations but still it does generate an
>
>
>
> >>>>> empty swagger.yaml for interfaces KmopResources and
>
>
>
> >>>>> KmopDienstverlener although I noticed that for these interfaces
>
> >>>>> the
>
>
>
> >>>>> @Path() annotation was commented out (as I included it in the
>
>
>
> >>>>> server declaration). After providing an empty @Path("")
>
> >>>>> declaration on
>
> >>>> the API interface classes everything worked.
>
>
>
>
>
> >>>>> Thanks for the support.
>
>
>
>
>
> >>>>> -----Original Message-----
>
>
>
>
>
> >>>>> From: Andriy Redko <dr...@gmail.com>
>
>
>
>
>
> >>>>> Sent: dinsdag 23 mei 2023 3:42
>
>
>
>
>
> >>>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>
>
>
> >>>>> dev@cxf.apache.org
>
>
>
>
>
> >>>>> Subject: Re: How to setup multiple JAXRS server endpoints
>
>
>
>
>
> >>>>> Hi Jean,
>
>
>
>
>
> >>>>> The main problem to configure Swagger property in your particular
>
>
>
> >>>>> case is that the server address is not "known" or "introspectable"
>
> >>>>> for
>
> >>>> Swagger.
>
>
>
> >>>>> Intuitively, it has to be set manually using basePath to the,
>
>
>
> >>>>> essentially, the server address
>
>
>
>
>
> >>>>> part:
>
>
>
>
>
> >>>>>  - /op/services/accounts
>
>
>
>
>
> >>>>>  - /op/services/resources
>
>
>
>
>
> >>>>>  - /op/services/dienstverlener
>
>
>
>
>
> >>>>> You could read more about other Swagger properties you have asked
> here:
>
>
>
> >>>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Int
>
> >>>>> e
>
>
>
> >>>>> gration-and-Configuration#configuration-properties
>
>
>
>
>
> >>>>> You definitely need to set usePathBasedConfig to "true" otherwise
>
>
>
> >>>>> you will see the same Swagger specs for all servers. We have a
>
>
>
> >>>>> sample here which uses 2 jaxrs:server
>
>
>
>
>
> >>>>> instances:
>
>
>
> >>>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma
>
> >>>>> i
>
>
>
> >>>>> n/release/samples/jax_rs/description_swagger2_web
>
>
>
>
>
> >>>>> Regarding SwaggerUI, I think the value for each of those should be
>
>
>
> >>>>> set to,
>
>
>
> >>>>> respectively:
>
>
>
>
>
> >>>>>  - /op/services/accounts/swagger.yaml
>
>
>
>
>
> >>>>>  - /op/services/resources/swagger.yaml
>
>
>
>
>
> >>>>>  - /op/services/dienstverlener/swagger.yaml
>
>
>
>
>
> >>>>> I believe this is matching your settings already, except the
>
>
>
> >>>>> usePathBasedConfig part. The example referred above could be
>
>
>
> >>>>> helpful, my apologies if I missed something, there are quite a lot
>
>
>
> >>>>> of questions :-) The fact that the generated Swagger specification
>
>
>
> >>>>> is empty is unexpected - it should not happen when JAX-RS
>
> >>>>> resources
>
> >>>> are properly configured.
>
>
>
>
>
> >>>>> Thank you.
>
>
>
>
>
> >>>>> Best Regards,
>
>
>
>
>
> >>>>>     Andriy Redko
>
>
>
>
>
> >>>>>>  RE: How to setup multiple JAXRS server endpoints
>
>
>
>
>
> >>>>>> Hi Andriy,
>
>
>
>
>
> >>>>>> I am not quite understanding how to correctly configure the
>
>
>
> >>>>> Swagger2Feature.
>
>
>
>
>
> >>>>>> Referring to the attached cxf-endpoints configuration I (as a
>
>
>
> >>>>>> test)
>
>
>
>
>
> >>>>>> created
>
>
>
>
>
> >>>>>> 3 JAXRS server instances:
>
>
>
>
>
> >>>>>> 1.      A* KmopApiServer* server for the*
>
>
>
>
>
> >>>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving
>
>
>
>
>
> >>>>>> requests for URI path:
>
>
>
>
>
> >>>>>>        * <protocol>**//<host:<port>/op/services/accounts*
>
>
>
>
>
> >>>>>>    ‘op’  = root path of the web application
>
>
>
>
>
> >>>>>>             ‘services’ = servlet path of the CXF-servlet
>
>
>
>
>
> >>>>>>       The address of the server is set to ‘/accounts’ and the
>
>
>
> >>>>>> @Path(…)
>
>
>
>
>
> >>>>>>       annotation on the interface class was cleared.
>
>
>
>
>
> >>>>>> 2.      A* Kmop**Resources**ApiServer* server for the*
>
> >>>> be.dvtm.aeo.op.*
>
>
>
>
>
> >>>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving
>
>
>
>
>
> >>>>>> requests for URI path:
>
>
>
>
>
> >>>>>>        * <protocol>**//<host:<port>/op/services/**resources*
>
>
>
>
>
> >>>>>> The address of the server is set to ‘/resources’ and the @Path(…)
>
>
>
>
>
> >>>>>> annotation on the interface class was cleared.
>
>
>
>
>
> >>>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*
>
>
>
> >>>>> be.dvtm.aeo.op.*
>
>
>
>
>
> >>>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving
>
>
>
>
>
> >>>>>> requests for URI path:
>
>
>
>
>
> >>>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*
>
>
>
>
>
> >>>>>> The address of the server is set to ‘/dienstverlener’ and the
>
>
>
>
>
> >>>>>> @Path(…) annotation on the interface class was cleared.
>
>
>
>
>
> >>>>>> For each of these server instances I’ve set the Swagger2Feature
>
>
>
>
>
> >>>>>> with configuration as indicated in the attached cxf-endpoints.xml.
>
>
>
>
>
> >>>>>> With regard to the configurations for the Swagger2Feature I’ve
>
> >>>>>> the
>
>
>
>
>
> >>>>>> following questions:
>
>
>
>
>
> >>>>>> a)      Referring to *
>
> >>>> https://cxf.apache.org/docs/swagger2feature.html*
>
>
>
>
>
> >>>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you
>
>
>
>
>
> >>>>>> clarify on the following configuration parameters:
>
>
>
>
>
> >>>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘
>
>
>
>
>
> >>>>>> /op/services’) or to the JAX-RS server instance (e.g.
>
>
>
>
>
> >>>>>> ‘/op/services/accounts’) or still something else? Is it used to
>
>
>
>
>
> >>>>>> resolve service classes or is it just for documentation in the
>
>
>
> >>>>>> swagger
>
>
>
> >>>>> file?
>
>
>
>
>
> >>>>>> *ii.    ** resourcePackage* – the description mentions ‘package
> names’
>
>
>
>
>
> >>>>>> while the default mentions ‘service classes’? Service 2 and 3
>
>
>
> >>>>>> above
>
>
>
>
>
> >>>>>> are within the same package (generated from the same yaml
>
>
>
>
>
> >>>>>> specification that included both interfaces).
>
>
>
>
>
> >>>>>> *iii.   ** ig**noreRoutes* – is this taken into account when
>
>
>
>
>
> >>>>>> scanAllResources=false?
>
>
>
>
>
> >>>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter
>
> >>>> value
>
>
>
>
>
> >>>>>> (cf. question ‘a’)?
>
>
>
>
>
> >>>>>> b)      What would be the correct URL to generate a swagger.yaml
>
> >>>>>> file
>
>
>
> >>>>> for
>
>
>
>
>
> >>>>>> each of the above interfaces? Initially I called:
>
>
>
>
>
> >>>>>> *i.     **
>
>
>
> >>>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*
>
>
>
>
>
> >>>>>> *ii.    **
>
>
>
> >>>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*
>
>
>
>
>
> >>>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*
>
>
>
>
>
> >>>>>> *lener/swagger.yaml*
>
>
>
>
>
> >>>>>>    All three requests delivered the same yaml specification,
>
>
>
> >>>>>> namely
>
>
>
> >>>>> the one
>
>
>
>
>
> >>>>>>       for interface* KmopApiServer*?
>
>
>
>
>
> >>>>>> c)      I tried to debug the processing of the requests under ‘b)’
>
> >>>>>> and
>
>
>
> >>>>> this
>
>
>
>
>
> >>>>>> is done by the class JAXRSInterceptor#processRequest where the
>
>
>
>
>
> >>>>>> MessageImpl object for request “ii.” looks like the one attached.
>
>
>
>
>
> >>>>>> It finds 3 resource
>
>
>
>
>
> >>>>>> classes:
>
>
>
>
>
> >>>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl
>
>
>
>
>
> >>>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource
>
>
>
>
>
> >>>>>>       org.apache
>
>

RE: Request mapping warnings

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
Hi all,



As a test I removed the @org.springframework.stereotype.Service(“
*KmopDienstverlenerApi*”) annotation on my service implementation class. So
no @Service annotations further exist. Still when checking the return of
*JAXRSUtils.**getRootResources*(Message message) via breakpoint I

Still notice that my service classes are listed twice in the return result
*List<ClassResourceInfo>*.



The only annotations I’ve left in my code are:

   - standard JAX-RS annotations:
   javax.ws.rs.[GET|POST|Consumes|Produces|HeaderParam|PathParam|QueryParam|Path|core.MediaType|core.Response]
   - io.swagger.v3.oas.annotations.*

I suppose none of these would be responsible for an extra registration of
my service classes.



So the only point where service registration occurs is in the bean
declaration file cxf-endpoint.xml, see attachment. The only thing I can
think of a possible double registration in this file is the declaration of
the OpenApiFeature (e.g. <bean id=”*KmopOpenApiFeature*” …> ) for each
resource endpoint in addition to the <jaxrs:server /> declaration using
this OpenApiFeature.

But I would assume that configuring the OpenApiFeature, through a bean
declaration, wouldn’t register a service.



The ‘imported’ resources context-v2.xml and onderneming-context.xml define
some <jaxws:client/> instances that have nothing to do with these JAX-WS/RS
endpoints declared in this file.



Is there something I can trace into to see when a service gets registered
as a *ClassResourceInfo *?



Regards,



J.P. Urkens

*From:* Andrey Redko <dr...@gmail.com>
*Sent:* woensdag 19 juli 2023 19:30
*To:* Jean Pierre URKENS <je...@devoteam.com>
*Cc:* Daniel Kulp <de...@cxf.apache.org>
*Subject:* Re: Request mapping warnings



Hi Jean,



Indeed it looks like you have the same resource registered twice hence the
warning. It may come from the use of automatic resource scans and manual
resource registration.

Best Regards,
    Andriy Redko



On Wed, Jul 19, 2023, 7:39 AM Jean Pierre URKENS <
jean-pierre.urkens@devoteam.com> wrote:

Still some minor issue related to request mapping.

I notice I am getting warnings like:

*2023-07-19 13:08:23,022 [T8N1TP1-4] WARN
(SID=8806F673DEC6B53D9248AF0DD81F6882)
(org.apache.cxf.jaxrs.model.OperationResourceInfoComparatorBase:102) - Both
be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#getDvlById
and
be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#getDvlById
are equal candidates for handling the current request which can lead to
unpredictable results*

Obvious that they are equal candidates because they are the same class. But
what is the cause of this double detection?

Is it because when *JAXRSUtils.**getRootResources*(Message message)  gets
called, I see that it contains 4 entries:

·       (twice) KmopDienstverlenerApiServiceImpl -> my service endpoint

·       io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

·       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService

So twice my service implementation, I wouldn’t know why this is the case?

On my classpath I have set:

·       cxf-rt-rs-service-description-3.5.6.jar                 -> this
handles request for ‘_wadl’

·       cxf-rt-rs-service-description-openapi-v3-3.5.6.jar      -> this
handles request for ‘openapi.[yaml|json]’

·       cxf-rt-rs-service-description-swagger-ui-3.5.6.jar      -> this
handles request for ‘Swagger documentation’

would this be a cause for my service endpoint to appear multiple times?
Aside from that I have no idea what could cause this.

J.P.

-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: donderdag 13 juli 2023 18:24
To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
Subject: Re: How to setup multiple JAXRS server endpoints

Got it, thank you (the Swagger sometimes does surprising things).

Thursday, July 13, 2023, 1:33:07 AM, you wrote:

JPU> The @Parameter annotation seems to be ignored at this level.

JPU> -----Original Message-----

JPU> From: Jean Pierre URKENS <je...@devoteam.com>

JPU> Sent: donderdag 13 juli 2023 7:11

JPU> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'

JPU> <de...@cxf.apache.org>

JPU> Subject: RE: How to setup multiple JAXRS server endpoints

JPU> Yes, SwaggerUI works too!

JPU> I noticed that v2.x of swagger-jaxrs relates to OpenApi v3.1.x

JPU> while my spec is compliant with OpenApi v3.0.x, so I am going to

JPU> stick with v2.1.13 which seems to be that last version for OpenApi
v3.0.x.

JPU> I thought the @Parameter only applied to input parameters ("query",

JPU> "header", "path" or "cookie" parameters), but I'll give it a try.

JPU> J.P.

JPU> -----Original Message-----

JPU> From: Andriy Redko <dr...@gmail.com>

JPU> Sent: woensdag 12 juli 2023 22:16

JPU> To: Jean Pierre URKENS <je...@devoteam.com>;

JPU> dev@cxf.apache.org

JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

JPU> That's awesome, have you got SwaggerUI working as well?

JPU> Yes, you could use 2.2.15 (we already updated to this version, no

JPU> regressions). It seems like the description applies to the whole

JPU> schema (which is the same for both properties), may be you could

JPU> use @Parameter

JPU> instead:

JPU> @Parameter(description="The description I want for prop1")

JPU> Thank you.

JPU> Best Regards,

JPU>     Andriy Redko

>> Hi Andriy,

>> After having migrated everything to "io.swagger.v3.oas.annotations.*"

>> the swagger endpoints for each of my services became active.

>> So far so good, but I do notice that there are discrepancies when

>> annotating models, e.g.:

>>  public class Model1 {

>>   @Schema(description="The description I want for prop1")

>>    private Model2 prop1;

>>   @Schema(description="The description I want for prop2")

>>    private Model2 prop2;

>>   ...

>> }

>> When I generate the openapi.[json|yaml] specification I see that both

>> prop1 and prop2 have a reference to the schema component "Model2"

>> with description ' The description I want for prop2' which is

>> inappropriate for 'prop1'.

>> It is not unlikely to have multiple properties within one Model that

>> are of the same class but are semantically used in a different context.
E.g.

>> something as simple as a ShipmentOrder having two 'Address'

>> properties 'from' and 'to' would result in wrong API documentation.

>> I am aware it has nothing to do with CXF but rather with

>> swagger-jaxrs2-vx.y.z.jar and depending libraries. CXF-3.5.6 has

>> dependency on swagger-jaxrs2-2.1.13.jar. Would it be an issue to

>> replace this dependency with e.g. swagger-jaxrs2-2.2.15.jar (latest

>> stable release according to maven central repo)?

>> J.P.

>> -----Original Message-----

>> From: Jean Pierre URKENS <je...@devoteam.com>

>> Sent: woensdag 12 juli 2023 8:25

>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'

>> <de...@cxf.apache.org>

>> Subject: RE: How to setup multiple JAXRS server endpoints I seem to

>> be mistaken here, the endpoint was loaded (I did a manual HTTP GET

>> test to the endpoint to verify this) although no breakpoints where

>> hit during startup.

>> I am first going to complete the migration to

>> "io.swagger.v3.oas.annotations.*" annotations for all endpoints and

>> then I am going to test again.

>> The application is composed of libraries, some of which use SLF4J but

>> most use LOG4J for logging.

>> J.P.

>> -----Original Message-----

>> From: Andriy Redko <dr...@gmail.com>

>> Sent: woensdag 12 juli 2023 1:13

>> To: Jean Pierre URKENS <je...@devoteam.com>;

>> dev@cxf.apache.org

>> Subject: Re: How to setup multiple JAXRS server endpoints Hi Jean,

>> The

>> OpenApiFeature$Portable#initiliaze(…) should definitely be called

>> (otherwise you shouldn't even see the openapi.json endpoint), so I am

>> not sure why these are not triggering for you.

>>

>> For logging, it seems like you are using SLF4J

>> (org.apache.cxf.common.logging.Slf4jLogger),

>> and also reload4j (aka log4j), why do you need both?

>> Thank you.

>> Best Regards,

>>     Andriy Redko

JPU>>> After some code investigation:



JPU>>> OpenApiFeature implements SwaggerUiSupport and in its

JPU>>> portable#registerSwaggerUiResources(…) method it will call

JPU>>> SwaggerUiSupport#getSwaggerUi(…) which will register the

JPU> SwaggerUiService.



JPU>>> I have put breakpoints on:

JPU>>>    - OpenApiFeature$Portable#initiliaze(…)

JPU>>>    - SwaggerUiService constructor

JPU>>>    - SwaggerUiSupport#getSwaggerUi(…)



JPU>>> but none of them are hit when starting my application?



JPU>>> Although the (spring) logging shows all beans in my

JPU>>> cxf-endpoints.xml have been created?

JPU>>> The *WADL* and *OpenAPI* endpoints to get the specification work.

JPU>>> Even the actual endpoint seems to work although I didn’t hit any

JPU>>> of the breakpoint?



JPU>>> CXF, also doesn’t seem to log a lot, I am hardly getting any log

JPU>>> entries although log level I set to DEBUG.

JPU>>> My logging (except wire message logging) for cxf is setup

JPU>>> correctly (I

JPU>>> think):

JPU>>>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line

JPU>>>    ‘org.apache.cxf.common.logging.Slf4jLogger’

JPU>>>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and

JPU>>>    reload4j-1.2.19.jar are on the classpath

JPU>>>    - the log4j.properties file contains the line:

JPU>>>    ‘log4j.logger.org.apache.cxf=DEBUG’



JPU>>> There are no special instructions mentioned on

JPU>>> https://cxf.apache.org/docs/general-cxf-logging.html so the above

JPU>>> should work (it works for all other packages I use in my
application).



JPU>>> J.P.

JPU>>> *From:* Jean Pierre URKENS <je...@devoteam.com>

JPU>>> *Sent:* dinsdag 11 juli 2023 9:58

JPU>>> *To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <

dev@cxf.apache.org>>>>

JPU>>> *Subject:* RE: How to setup multiple JAXRS server endpoints



JPU>>> Hi Andriy,



JPU>>> As a test I removed all JAX-RS endpoints that use Swagger v2

JPU>>> annotations from my configuration file (see attachment).

JPU>>> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger

JPU>>> v3 annotations, using the OpenApiFeature i.o. Swagger2Feature.

JPU>>> If I run my server with this configuration I only get the

JPU>>> (working)

JPU>>> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint:



JPU>>> So there is some configuration missing to detect/activate the

JPU>>> Swagger endpoint. When I look at the samples that come with the

JPU>>> distribution of CXF (I am using v3.5.6) nothing special seems to

JPU>>> be

JPU> configured to activate this?

JPU>>> Do you have any idea how the SwaggerUiService is picked up when

JPU> loading?



JPU>>> J.P.



JPU>>> -----Original Message-----

JPU>>> From: Andriy Redko <dr...@gmail.com>

JPU>>> Sent: dinsdag 11 juli 2023 3:44

JPU>>> To: Jean Pierre URKENS <je...@devoteam.com>;

JPU>>> dev@cxf.apache.org

JPU>>> Subject: Re: How to setup multiple JAXRS server endpoints



JPU>>> Hi Jean,



JPU>>> I guess you figured one issue, swagger.json -> openapi.json, but

JPU>>> to be honest we have never tested or envisioned the application

JPU>>> that would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same

JPU>>> time, I am afraid this is just not supported. You may get things

JPU>>> back on track when going with OpenAPI 3.0 for all services.



JPU>>> Thank you.



JPU>>> Best Regards,

JPU>>>     Andriy Redko



>>>> Hi Andriy,





>>>> I am trying to trace the difference in handling with another

>>>> application where I’ve got only one CXF service endpoint that uses

>>>> swagger v3 openapi annotations.



>>>> There I see that when handling the Swagger page request (

>>>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json)

>>>> the JAXRSInInterceptor is calling:





>>>> *JAXRSUtils.**getRootResources*(Message message)





>>>> It contains 4 entries:



>>>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint

>>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

>>>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService













>>>> On the application described below with the service ‘oidcsim’ when

>>>> calling the swagger page request

>>>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the

>>>> result of the getRootResources doesn’t contain the

>>>> ClassResourceInfo ‘ SwaggerUiService’. It only contains 3 entries:



>>>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)

>>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource





>>>> The SwaggerUiService is the one that is configured to handle the

JPU>>> ‘api-docs’

>>>> path-request. Since it is missing the request is tried to match

>>>> with the other two resources but fails, hence ‘NOT FOUND’ exception.





>>>> I can’t trace back where these rootResources are set and why the

>>>> SwaggerUiService’ isn’t listed.





>>>> J.P.



>>>> *From:* Jean Pierre URKENS <je...@devoteam.com>

>>>> *Sent:* maandag 10 juli 2023 13:43

>>>> *To:* 'Andriy Redko' <dr...@gmail.com>

>>>> *Subject:* RE: How to setup multiple JAXRS server endpoints





>>>> Andriy,





>>>> I am trying to switch from Swagger v2 to OpenApi v3 annotations

>>>> basically because my starting point is an OpenApi v3.0.7 yaml file

>>>> description and OpenAPI seems to be the way forward.



>>>> For applications where I have only one CXF JAX-RS endpoint exposed

>>>> I had no problems converting. However as soon as there are multiple

>>>> endpoints I run into troubles.





>>>> So, to recall, I've an application exposing 3 JAX-RS endpoints that

>>>> where previously annotated with swagger v2 annotations (i.e.

>>>> package

>>>> io.swagger.annotations.*) which I migrated to



>>>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*).

>>>> In accordance I altered my CXF JAX-RS endpoint configuration from

>>>> (only showing relevant parts, see attachment for full setup):





>>>>                <!-- CXF Swagger2Feature -->



>>>>                <bean id="SwaggerUiConfigOidcApi"

>>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>>>>                               <property name="queryConfigEnabled"



>>>>                               <property name="url"

>>>> value="/op/services/oidcsim/swagger.yaml"/>



>>>>                </bean>



>>>>                <bean id="Swagger2FeatureOidcApi"

>>>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">



>>>>                               <property name="basePath"

>>>> value="/op/services/oidcsim"/>



>>>>                               <property name="usePathBasedConfig"



>>>>                               <property name="resourcePackage"

>>>> value="be.dvtm.aeo.op.oidc"/>



>>>>                               <property name="supportSwaggerUi"



>>>>                               <property name="swaggerUiConfig"

>>>> ref="SwaggerUiConfigOidcApi"/>



>>>>                </bean>



>>>>                <jaxrs:server id="OidcProviderApiServer"

>>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>>>>                               ....



>>>>                               <jaxrs:features>



>>>>                                              <ref

>>>> bean="Swagger2FeatureOidcApi" />



>>>>                               </jaxrs:features>



>>>>                               ...



>>>>                </jaxrs:server>





>>>> TO:



>>>>                <!-- CXF OpenAPIFeature -->



>>>>                <bean id="OidcSwaggerUiConfig"

>>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>>>>                               <property name="queryConfigEnabled"



>>>>                               <property name="url"

>>>> value="openapi.json"/>



>>>>                </bean>



>>>>                <bean id="OidcOpenApiFeature"

>>>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">



>>>>                               <property name="supportSwaggerUi"



>>>>                               <property name="swaggerUiConfig"

>>>> ref="OidcSwaggerUiConfig"/>



>>>>                               <property name="swaggerUiVersion"



>>>>                               <property name="scan" value="false"/>



>>>>                               <property name="useContextBasedConfig"



>>>>                               <property name="resourcePackages"

>>>> value="be.dvtm.aeo.op.oidc"/>



>>>>                </bean>



>>>>                <jaxrs:server id="OidcProviderApiServer"

>>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>>>>                               ....



>>>>                               <jaxrs:features>



>>>>                                              <ref

JPU>>> bean="OidcOpenApiFeature"



>>>>                               </jaxrs:features>



>>>>                               ...



>>>>                </jaxrs:server>









>>>> Now when starting my application and navigating to the root part "

>>>> http://localhost:localPort/op/services" I get an overview of all my

>>>> endpoints:





>>>> Now there are 3 RESTful service endpoints setup:



>>>>    1. ‘oidcsim’ which I switched to swagger v3 annotations

>>>>    2. ‘openapi’ currently still swagger v2 annotations

>>>>    3. ‘sdx’ currently still swagger v2 annotations





>>>> all endpoints work except for the ‘swagger endpoint address for the

>>>> oidcsim

>>>> endpoint:

>>>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services

>>>> /o

>>>> i

>>>> dcsim/swagger.json



>>>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*

>>>> endpoint of the oidcsim resource. I am getting an error (the value

>>>> of the ‘url’ query parameter isn’t relevant):





>>>>         “WebApplicationException has been caught, status: 404,

>>>> message: HTTP 404 Not Found”





>>>> When I try (without the ‘/oidcsim’ context):

>>>> http://l-p53-008:8081/op/services/api-docs I get:



>>>>                “No service was found.”





>>>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs

>>>> doesn’t exist, where as the endpoint

>>>> http://l-p53-008:8081/op/services/api-docs does exist but no

>>>> service

JPU>>> description is found?



>>>> Of course my intention is to get working, as previously with the

>>>> swagger v2 setup for which I then specifically added the

>>>> *Swagger2Feature* config

>>>> parameters:



>>>>                               <property name="basePath"

>>>> value="/op/services/oidcsim"/>



>>>>                               <property name="usePathBasedConfig"





>>>> But I don’t find the according configuration options for the

>>>> *OpenApiFeature* class or whether I should configure this in

>>>> another way.





>>>> Any suggestions on this?





>>>> Regards,





>>>> J.P.









>>>> -----Original Message-----

>>>> From: Andriy Redko <dr...@gmail.com>

>>>> Sent: donderdag 25 mei 2023 2:27

>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>>> dev@cxf.apache.org

>>>> Subject: Re: How to setup multiple JAXRS server endpoints





>>>> Hi Jean,





>>>> You may run into Swagger JAX-RS scanner limitations, as far as I

>>>> can tell - it checks class annotations for SwaggerDefinition, does

>>>> not traverse the hierarchy [1].





>>>> [1]

>>>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagge

>>>> r-

>>>> j

>>>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194





>>>> Best Regards,



>>>>     Andriy Redko





>>>>>  RE: How to setup multiple JAXRS server endpoints





>>>>> Still one question );





>>>>> The generated swagger file doesn’t take into account the



>>>>> @SwaggerDefintion on my interface classes?





>>>>> As a test I looked at



>>>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m

>>>>> a



>>>>> in/release/samples/jax_rs/description_swagger2_web**



>>>>> and** modified** sample2*



>>>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m

>>>>> a



>>>>> in/release/samples/jax_rs/description_swagger2_web



>>>>> and modified sample2> as follows:





>>>>>    @Path("/sample2")





>>>>>       @Api(value = "/sample2",authorizations=



>>>>>       {@Authorization(value="bearer")},description = "Sample2

>>>> (modified) JAX-RS



>>>>>       service with Swagger documentation")





>>>>>       @SwaggerDefinition(





>>>>>               info = @Info(





>>>>>                       description = "Sample2 server",





>>>>>                       version="1.0",





>>>>>                       title = "Test2",





>>>>>                       contact = @Contact(name = "J.P. Urkens",email =
"



>>>>>       *jean-pierre.urkens@devoteam.com* <

>>>> jean-pierre.urkens@devoteam.com>



>>>>>       ")),





>>>>>               securityDefinition =



>>>>>       @SecurityDefinition(apiKeyAuthDefinitions=



>>>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name=
<*%7B@ApiKeyAuthDefinition(key=>

>>>> "A

>>>> u

>>>> thorization",description="Use*



>>>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer



>>>>>       &lt;accessToken&gt;'")})





>>>>>       )





>>>>>       public class Sample2 {...}





>>>>> This correctly generates the ‘securityDefintions’ in the swagger file.





>>>>> If include the same @SwaggerDefinition and the authorizations on



>>>>> the @Api annotation as above in my interface classes then the



>>>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?





>>>>> Any idea what I might be missing?





>>>>> Regards,





>>>>> J.P.





>>>>> -----Original Message-----



>>>>> From: Jean Pierre URKENS <je...@devoteam.com>



>>>>> Sent: dinsdag 23 mei 2023 12:52



>>>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <



>>>>> Subject: RE: How to setup multiple JAXRS server endpoints





>>>>> Hi Andriy,





>>>>> I added the parameter usePathBasedConfig=true to the



>>>>> Swagger2Feature bean declarations but still it does generate an



>>>>> empty swagger.yaml for interfaces KmopResources and



>>>>> KmopDienstverlener although I noticed that for these interfaces

>>>>> the



>>>>> @Path() annotation was commented out (as I included it in the



>>>>> server declaration). After providing an empty @Path("")

>>>>> declaration on

>>>> the API interface classes everything worked.





>>>>> Thanks for the support.





>>>>> -----Original Message-----





>>>>> From: Andriy Redko <dr...@gmail.com>





>>>>> Sent: dinsdag 23 mei 2023 3:42





>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;



>>>>> dev@cxf.apache.org





>>>>> Subject: Re: How to setup multiple JAXRS server endpoints





>>>>> Hi Jean,





>>>>> The main problem to configure Swagger property in your particular



>>>>> case is that the server address is not "known" or "introspectable"

>>>>> for

>>>> Swagger.



>>>>> Intuitively, it has to be set manually using basePath to the,



>>>>> essentially, the server address





>>>>> part:





>>>>>  - /op/services/accounts





>>>>>  - /op/services/resources





>>>>>  - /op/services/dienstverlener





>>>>> You could read more about other Swagger properties you have asked
here:



>>>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Int

>>>>> e



>>>>> gration-and-Configuration#configuration-properties





>>>>> You definitely need to set usePathBasedConfig to "true" otherwise



>>>>> you will see the same Swagger specs for all servers. We have a



>>>>> sample here which uses 2 jaxrs:server





>>>>> instances:



>>>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma

>>>>> i



>>>>> n/release/samples/jax_rs/description_swagger2_web





>>>>> Regarding SwaggerUI, I think the value for each of those should be



>>>>> set to,



>>>>> respectively:





>>>>>  - /op/services/accounts/swagger.yaml





>>>>>  - /op/services/resources/swagger.yaml





>>>>>  - /op/services/dienstverlener/swagger.yaml





>>>>> I believe this is matching your settings already, except the



>>>>> usePathBasedConfig part. The example referred above could be



>>>>> helpful, my apologies if I missed something, there are quite a lot



>>>>> of questions :-) The fact that the generated Swagger specification



>>>>> is empty is unexpected - it should not happen when JAX-RS

>>>>> resources

>>>> are properly configured.





>>>>> Thank you.





>>>>> Best Regards,





>>>>>     Andriy Redko





>>>>>>  RE: How to setup multiple JAXRS server endpoints





>>>>>> Hi Andriy,





>>>>>> I am not quite understanding how to correctly configure the



>>>>> Swagger2Feature.





>>>>>> Referring to the attached cxf-endpoints configuration I (as a



>>>>>> test)





>>>>>> created





>>>>>> 3 JAXRS server instances:





>>>>>> 1.      A* KmopApiServer* server for the*





>>>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving





>>>>>> requests for URI path:





>>>>>>        * <protocol>**//<host:<port>/op/services/accounts*





>>>>>>    ‘op’  = root path of the web application





>>>>>>             ‘services’ = servlet path of the CXF-servlet





>>>>>>       The address of the server is set to ‘/accounts’ and the



>>>>>> @Path(…)





>>>>>>       annotation on the interface class was cleared.





>>>>>> 2.      A* Kmop**Resources**ApiServer* server for the*

>>>> be.dvtm.aeo.op.*





>>>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving





>>>>>> requests for URI path:





>>>>>>        * <protocol>**//<host:<port>/op/services/**resources*





>>>>>> The address of the server is set to ‘/resources’ and the @Path(…)





>>>>>> annotation on the interface class was cleared.





>>>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*



>>>>> be.dvtm.aeo.op.*





>>>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving





>>>>>> requests for URI path:





>>>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*





>>>>>> The address of the server is set to ‘/dienstverlener’ and the





>>>>>> @Path(…) annotation on the interface class was cleared.





>>>>>> For each of these server instances I’ve set the Swagger2Feature





>>>>>> with configuration as indicated in the attached cxf-endpoints.xml.





>>>>>> With regard to the configurations for the Swagger2Feature I’ve

>>>>>> the





>>>>>> following questions:





>>>>>> a)      Referring to *

>>>> https://cxf.apache.org/docs/swagger2feature.html*





>>>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you





>>>>>> clarify on the following configuration parameters:





>>>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘





>>>>>> /op/services’) or to the JAX-RS server instance (e.g.





>>>>>> ‘/op/services/accounts’) or still something else? Is it used to





>>>>>> resolve service classes or is it just for documentation in the



>>>>>> swagger



>>>>> file?





>>>>>> *ii.    ** resourcePackage* – the description mentions ‘package
names’





>>>>>> while the default mentions ‘service classes’? Service 2 and 3



>>>>>> above





>>>>>> are within the same package (generated from the same yaml





>>>>>> specification that included both interfaces).





>>>>>> *iii.   ** ig**noreRoutes* – is this taken into account when





>>>>>> scanAllResources=false?





>>>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter

>>>> value





>>>>>> (cf. question ‘a’)?





>>>>>> b)      What would be the correct URL to generate a swagger.yaml

>>>>>> file



>>>>> for





>>>>>> each of the above interfaces? Initially I called:





>>>>>> *i.     **



>>>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*





>>>>>> *ii.    **



>>>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*





>>>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*





>>>>>> *lener/swagger.yaml*





>>>>>>    All three requests delivered the same yaml specification,



>>>>>> namely



>>>>> the one





>>>>>>       for interface* KmopApiServer*?





>>>>>> c)      I tried to debug the processing of the requests under ‘b)’

>>>>>> and



>>>>> this





>>>>>> is done by the class JAXRSInterceptor#processRequest where the





>>>>>> MessageImpl object for request “ii.” looks like the one attached.





>>>>>> It finds 3 resource





>>>>>> classes:





>>>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl





>>>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource





>>>>>>       org.apache

Re: Request mapping warnings

Posted by Andrey Redko <dr...@gmail.com>.
Hi Jean,

Indeed it looks like you have the same resource registered twice hence the
warning. It may come from the use of automatic resource scans and manual
resource registration.

Best Regards,
    Andriy Redko

On Wed, Jul 19, 2023, 7:39 AM Jean Pierre URKENS <
jean-pierre.urkens@devoteam.com> wrote:

> Still some minor issue related to request mapping.
>
> I notice I am getting warnings like:
>
>    *2023-07-19 13:08:23,022 [T8N1TP1-4] WARN
>       (SID=8806F673DEC6B53D9248AF0DD81F6882)
>       (org.apache.cxf.jaxrs.model.OperationResourceInfoComparatorBase:102) - Both
>       be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#getDvlById
>       and
>       be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#getDvlById
>       are equal candidates for handling the current request which can lead to
>       unpredictable results*
>
> Obvious that they are equal candidates because they are the same class. But
> what is the cause of this double detection?
>
> Is it because when* JAXRSUtils.**getRootResources*(Message message)  gets
> called, I see that it contains 4 entries:
>
> ·       (twice) KmopDienstverlenerApiServiceImpl -> my service endpoint
>
> ·       io.swagger.v3.jaxrs2.integration.resources.OpenApiResource
>
> ·       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService
>
> So twice my service implementation, I wouldn’t know why this is the case?
>
> On my classpath I have set:
>
> ·       cxf-rt-rs-service-description-3.5.6.jar                 -> this
> handles request for ‘_wadl’
>
> ·       cxf-rt-rs-service-description-openapi-v3-3.5.6.jar      -> this
> handles request for ‘openapi.[yaml|json]’
>
> ·       cxf-rt-rs-service-description-swagger-ui-3.5.6.jar      -> this
> handles request for ‘Swagger documentation’
>
> would this be a cause for my service endpoint to appear multiple times?
> Aside from that I have no idea what could cause this.
>
> J.P.
>
> -----Original Message-----
> From: Andriy Redko <dr...@gmail.com>
> Sent: donderdag 13 juli 2023 18:24
> To: Jean Pierre URKENS <je...@devoteam.com>;
> dev@cxf.apache.org
> Subject: Re: How to setup multiple JAXRS server endpoints
>
> Got it, thank you (the Swagger sometimes does surprising things).
>
> Thursday, July 13, 2023, 1:33:07 AM, you wrote:
>
> JPU> The @Parameter annotation seems to be ignored at this level.
>
> JPU> -----Original Message-----
>
> JPU> From: Jean Pierre URKENS <je...@devoteam.com>
>
> JPU> Sent: donderdag 13 juli 2023 7:11
>
> JPU> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'
>
> JPU> <de...@cxf.apache.org>
>
> JPU> Subject: RE: How to setup multiple JAXRS server endpoints
>
> JPU> Yes, SwaggerUI works too!
>
> JPU> I noticed that v2.x of swagger-jaxrs relates to OpenApi v3.1.x
>
> JPU> while my spec is compliant with OpenApi v3.0.x, so I am going to
>
> JPU> stick with v2.1.13 which seems to be that last version for OpenApi
> v3.0.x.
>
> JPU> I thought the @Parameter only applied to input parameters ("query",
>
> JPU> "header", "path" or "cookie" parameters), but I'll give it a try.
>
> JPU> J.P.
>
> JPU> -----Original Message-----
>
> JPU> From: Andriy Redko <dr...@gmail.com>
>
> JPU> Sent: woensdag 12 juli 2023 22:16
>
> JPU> To: Jean Pierre URKENS <je...@devoteam.com>;
>
> JPU> dev@cxf.apache.org
>
> JPU> Subject: Re: How to setup multiple JAXRS server endpoints
>
> JPU> Hi Jean,
>
> JPU> That's awesome, have you got SwaggerUI working as well?
>
> JPU> Yes, you could use 2.2.15 (we already updated to this version, no
>
> JPU> regressions). It seems like the description applies to the whole
>
> JPU> schema (which is the same for both properties), may be you could
>
> JPU> use @Parameter
>
> JPU> instead:
>
> JPU> @Parameter(description="The description I want for prop1")
>
> JPU> Thank you.
>
> JPU> Best Regards,
>
> JPU>     Andriy Redko
>
> >> Hi Andriy,
>
> >> After having migrated everything to "io.swagger.v3.oas.annotations.*"
>
> >> the swagger endpoints for each of my services became active.
>
> >> So far so good, but I do notice that there are discrepancies when
>
> >> annotating models, e.g.:
>
> >>  public class Model1 {
>
> >>   @Schema(description="The description I want for prop1")
>
> >>    private Model2 prop1;
>
> >>   @Schema(description="The description I want for prop2")
>
> >>    private Model2 prop2;
>
> >>   ...
>
> >> }
>
> >> When I generate the openapi.[json|yaml] specification I see that both
>
> >> prop1 and prop2 have a reference to the schema component "Model2"
>
> >> with description ' The description I want for prop2' which is
>
> >> inappropriate for 'prop1'.
>
> >> It is not unlikely to have multiple properties within one Model that
>
> >> are of the same class but are semantically used in a different context.
> E.g.
>
> >> something as simple as a ShipmentOrder having two 'Address'
>
> >> properties 'from' and 'to' would result in wrong API documentation.
>
> >> I am aware it has nothing to do with CXF but rather with
>
> >> swagger-jaxrs2-vx.y.z.jar and depending libraries. CXF-3.5.6 has
>
> >> dependency on swagger-jaxrs2-2.1.13.jar. Would it be an issue to
>
> >> replace this dependency with e.g. swagger-jaxrs2-2.2.15.jar (latest
>
> >> stable release according to maven central repo)?
>
> >> J.P.
>
> >> -----Original Message-----
>
> >> From: Jean Pierre URKENS <je...@devoteam.com>
>
> >> Sent: woensdag 12 juli 2023 8:25
>
> >> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'
>
> >> <de...@cxf.apache.org>
>
> >> Subject: RE: How to setup multiple JAXRS server endpoints I seem to
>
> >> be mistaken here, the endpoint was loaded (I did a manual HTTP GET
>
> >> test to the endpoint to verify this) although no breakpoints where
>
> >> hit during startup.
>
> >> I am first going to complete the migration to
>
> >> "io.swagger.v3.oas.annotations.*" annotations for all endpoints and
>
> >> then I am going to test again.
>
> >> The application is composed of libraries, some of which use SLF4J but
>
> >> most use LOG4J for logging.
>
> >> J.P.
>
> >> -----Original Message-----
>
> >> From: Andriy Redko <dr...@gmail.com>
>
> >> Sent: woensdag 12 juli 2023 1:13
>
> >> To: Jean Pierre URKENS <je...@devoteam.com>;
>
> >> dev@cxf.apache.org
>
> >> Subject: Re: How to setup multiple JAXRS server endpoints Hi Jean,
>
> >> The
>
> >> OpenApiFeature$Portable#initiliaze(…) should definitely be called
>
> >> (otherwise you shouldn't even see the openapi.json endpoint), so I am
>
> >> not sure why these are not triggering for you.
>
> >>
>
> >> For logging, it seems like you are using SLF4J
>
> >> (org.apache.cxf.common.logging.Slf4jLogger),
>
> >> and also reload4j (aka log4j), why do you need both?
>
> >> Thank you.
>
> >> Best Regards,
>
> >>     Andriy Redko
>
> JPU>>> After some code investigation:
>
> JPU>>> OpenApiFeature implements SwaggerUiSupport and in its
>
> JPU>>> portable#registerSwaggerUiResources(…) method it will call
>
> JPU>>> SwaggerUiSupport#getSwaggerUi(…) which will register the
>
> JPU> SwaggerUiService.
>
> JPU>>> I have put breakpoints on:
>
> JPU>>>    - OpenApiFeature$Portable#initiliaze(…)
>
> JPU>>>    - SwaggerUiService constructor
>
> JPU>>>    - SwaggerUiSupport#getSwaggerUi(…)
>
> JPU>>> but none of them are hit when starting my application?
>
> JPU>>> Although the (spring) logging shows all beans in my
>
> JPU>>> cxf-endpoints.xml have been created?
>
> JPU>>> The *WADL* and *OpenAPI* endpoints to get the specification work.
>
> JPU>>> Even the actual endpoint seems to work although I didn’t hit any
>
> JPU>>> of the breakpoint?
>
> JPU>>> CXF, also doesn’t seem to log a lot, I am hardly getting any log
>
> JPU>>> entries although log level I set to DEBUG.
>
> JPU>>> My logging (except wire message logging) for cxf is setup
>
> JPU>>> correctly (I
>
> JPU>>> think):
>
> JPU>>>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line
>
> JPU>>>    ‘org.apache.cxf.common.logging.Slf4jLogger’
>
> JPU>>>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and
>
> JPU>>>    reload4j-1.2.19.jar are on the classpath
>
> JPU>>>    - the log4j.properties file contains the line:
>
> JPU>>>    ‘log4j.logger.org.apache.cxf=DEBUG’
>
> JPU>>> There are no special instructions mentioned on
>
> JPU>>> https://cxf.apache.org/docs/general-cxf-logging.html so the above
>
> JPU>>> should work (it works for all other packages I use in my
> application).
>
> JPU>>> J.P.
>
> JPU>>> *From:* Jean Pierre URKENS <je...@devoteam.com>
>
> JPU>>> *Sent:* dinsdag 11 juli 2023 9:58
>
> JPU>>> *To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <
>
> dev@cxf.apache.org>>>>
>
> JPU>>> *Subject:* RE: How to setup multiple JAXRS server endpoints
>
> JPU>>> Hi Andriy,
>
> JPU>>> As a test I removed all JAX-RS endpoints that use Swagger v2
>
> JPU>>> annotations from my configuration file (see attachment).
>
> JPU>>> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger
>
> JPU>>> v3 annotations, using the OpenApiFeature i.o. Swagger2Feature.
>
> JPU>>> If I run my server with this configuration I only get the
>
> JPU>>> (working)
>
> JPU>>> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint:
>
>
>
> JPU>>> So there is some configuration missing to detect/activate the
>
> JPU>>> Swagger endpoint. When I look at the samples that come with the
>
> JPU>>> distribution of CXF (I am using v3.5.6) nothing special seems to
>
> JPU>>> be
>
> JPU> configured to activate this?
>
> JPU>>> Do you have any idea how the SwaggerUiService is picked up when
>
> JPU> loading?
>
> JPU>>> J.P.
>
> JPU>>> -----Original Message-----
>
> JPU>>> From: Andriy Redko <dr...@gmail.com>
>
> JPU>>> Sent: dinsdag 11 juli 2023 3:44
>
> JPU>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>
> JPU>>> dev@cxf.apache.org
>
> JPU>>> Subject: Re: How to setup multiple JAXRS server endpoints
>
> JPU>>> Hi Jean,
>
> JPU>>> I guess you figured one issue, swagger.json -> openapi.json, but
>
> JPU>>> to be honest we have never tested or envisioned the application
>
> JPU>>> that would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same
>
> JPU>>> time, I am afraid this is just not supported. You may get things
>
> JPU>>> back on track when going with OpenAPI 3.0 for all services.
>
> JPU>>> Thank you.
>
> JPU>>> Best Regards,
>
> JPU>>>     Andriy Redko
>
>
>
> >>>> Hi Andriy,
>
>
>
>
>
> >>>> I am trying to trace the difference in handling with another
>
> >>>> application where I’ve got only one CXF service endpoint that uses
>
> >>>> swagger v3 openapi annotations.
>
> >>>> There I see that when handling the Swagger page request (
>
> >>>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json)
>
> >>>> the JAXRSInInterceptor is calling:
>
>
>
>
>
> >>>> *JAXRSUtils.**getRootResources*(Message message)
>
>
>
>
>
> >>>> It contains 4 entries:
>
> >>>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint
>
> >>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource
>
> >>>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService
>
>
>
>
>
>
>
>
>
>
>
>
>
> >>>> On the application described below with the service ‘oidcsim’ when
>
> >>>> calling the swagger page request
>
> >>>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the
>
> >>>> result of the getRootResources doesn’t contain the
>
> >>>> ClassResourceInfo ‘ SwaggerUiService’. It only contains 3 entries:
>
> >>>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)
>
> >>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource
>
>
>
>
>
> >>>> The SwaggerUiService is the one that is configured to handle the
>
> JPU>>> ‘api-docs’
>
> >>>> path-request. Since it is missing the request is tried to match
>
> >>>> with the other two resources but fails, hence ‘NOT FOUND’ exception.
>
>
>
>
>
> >>>> I can’t trace back where these rootResources are set and why the
>
> >>>> SwaggerUiService’ isn’t listed.
>
>
>
>
>
> >>>> J.P.
>
> >>>> *From:* Jean Pierre URKENS <je...@devoteam.com>
>
> >>>> *Sent:* maandag 10 juli 2023 13:43
>
> >>>> *To:* 'Andriy Redko' <dr...@gmail.com>
>
> >>>> *Subject:* RE: How to setup multiple JAXRS server endpoints
>
>
>
>
>
> >>>> Andriy,
>
>
>
>
>
> >>>> I am trying to switch from Swagger v2 to OpenApi v3 annotations
>
> >>>> basically because my starting point is an OpenApi v3.0.7 yaml file
>
> >>>> description and OpenAPI seems to be the way forward.
>
> >>>> For applications where I have only one CXF JAX-RS endpoint exposed
>
> >>>> I had no problems converting. However as soon as there are multiple
>
> >>>> endpoints I run into troubles.
>
>
>
>
>
> >>>> So, to recall, I've an application exposing 3 JAX-RS endpoints that
>
> >>>> where previously annotated with swagger v2 annotations (i.e.
>
> >>>> package
>
> >>>> io.swagger.annotations.*) which I migrated to
>
> >>>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*).
>
> >>>> In accordance I altered my CXF JAX-RS endpoint configuration from
>
> >>>> (only showing relevant parts, see attachment for full setup):
>
>
>
>
>
> >>>>                <!-- CXF Swagger2Feature -->
>
> >>>>                <bean id="SwaggerUiConfigOidcApi"
>
> >>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">
>
> >>>>                               <property name="queryConfigEnabled"
>
> >>>>                               <property name="url"
>
> >>>> value="/op/services/oidcsim/swagger.yaml"/>
>
> >>>>                </bean>
>
> >>>>                <bean id="Swagger2FeatureOidcApi"
>
> >>>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">
>
> >>>>                               <property name="basePath"
>
> >>>> value="/op/services/oidcsim"/>
>
> >>>>                               <property name="usePathBasedConfig"
>
> >>>>                               <property name="resourcePackage"
>
> >>>> value="be.dvtm.aeo.op.oidc"/>
>
> >>>>                               <property name="supportSwaggerUi"
>
> >>>>                               <property name="swaggerUiConfig"
>
> >>>> ref="SwaggerUiConfigOidcApi"/>
>
> >>>>                </bean>
>
> >>>>                <jaxrs:server id="OidcProviderApiServer"
>
> >>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">
>
> >>>>                               ....
>
> >>>>                               <jaxrs:features>
>
> >>>>                                              <ref
>
> >>>> bean="Swagger2FeatureOidcApi" />
>
> >>>>                               </jaxrs:features>
>
> >>>>                               ...
>
> >>>>                </jaxrs:server>
>
>
>
>
>
> >>>> TO:
>
> >>>>                <!-- CXF OpenAPIFeature -->
>
> >>>>                <bean id="OidcSwaggerUiConfig"
>
> >>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">
>
> >>>>                               <property name="queryConfigEnabled"
>
> >>>>                               <property name="url"
>
> >>>> value="openapi.json"/>
>
> >>>>                </bean>
>
> >>>>                <bean id="OidcOpenApiFeature"
>
> >>>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">
>
> >>>>                               <property name="supportSwaggerUi"
>
> >>>>                               <property name="swaggerUiConfig"
>
> >>>> ref="OidcSwaggerUiConfig"/>
>
> >>>>                               <property name="swaggerUiVersion"
>
> >>>>                               <property name="scan" value="false"/>
>
> >>>>                               <property name="useContextBasedConfig"
>
> >>>>                               <property name="resourcePackages"
>
> >>>> value="be.dvtm.aeo.op.oidc"/>
>
> >>>>                </bean>
>
> >>>>                <jaxrs:server id="OidcProviderApiServer"
>
> >>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">
>
> >>>>                               ....
>
> >>>>                               <jaxrs:features>
>
> >>>>                                              <ref
>
> JPU>>> bean="OidcOpenApiFeature"
>
> >>>>                               </jaxrs:features>
>
> >>>>                               ...
>
> >>>>                </jaxrs:server>
>
>
>
>
>
>
>
>
>
> >>>> Now when starting my application and navigating to the root part "
>
> >>>> http://localhost:localPort/op/services" I get an overview of all my
>
> >>>> endpoints:
>
>
>
>
>
> >>>> Now there are 3 RESTful service endpoints setup:
>
> >>>>    1. ‘oidcsim’ which I switched to swagger v3 annotations
>
> >>>>    2. ‘openapi’ currently still swagger v2 annotations
>
> >>>>    3. ‘sdx’ currently still swagger v2 annotations
>
>
>
>
>
> >>>> all endpoints work except for the ‘swagger endpoint address for the
>
> >>>> oidcsim
>
> >>>> endpoint:
>
> >>>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services
>
> >>>> /o
>
> >>>> i
>
> >>>> dcsim/swagger.json
>
> >>>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*
>
> >>>> endpoint of the oidcsim resource. I am getting an error (the value
>
> >>>> of the ‘url’ query parameter isn’t relevant):
>
>
>
>
>
> >>>>         “WebApplicationException has been caught, status: 404,
>
> >>>> message: HTTP 404 Not Found”
>
>
>
>
>
> >>>> When I try (without the ‘/oidcsim’ context):
>
> >>>> http://l-p53-008:8081/op/services/api-docs I get:
>
> >>>>                “No service was found.”
>
>
>
>
>
> >>>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs
>
> >>>> doesn’t exist, where as the endpoint
>
> >>>> http://l-p53-008:8081/op/services/api-docs does exist but no
>
> >>>> service
>
> JPU>>> description is found?
>
> >>>> Of course my intention is to get working, as previously with the
>
> >>>> swagger v2 setup for which I then specifically added the
>
> >>>> *Swagger2Feature* config
>
> >>>> parameters:
>
> >>>>                               <property name="basePath"
>
> >>>> value="/op/services/oidcsim"/>
>
> >>>>                               <property name="usePathBasedConfig"
>
>
>
>
>
> >>>> But I don’t find the according configuration options for the
>
> >>>> *OpenApiFeature* class or whether I should configure this in
>
> >>>> another way.
>
>
>
>
>
> >>>> Any suggestions on this?
>
>
>
>
>
> >>>> Regards,
>
>
>
>
>
> >>>> J.P.
>
>
>
>
>
>
>
>
>
> >>>> -----Original Message-----
>
> >>>> From: Andriy Redko <dr...@gmail.com>
>
> >>>> Sent: donderdag 25 mei 2023 2:27
>
> >>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>
> >>>> dev@cxf.apache.org
>
> >>>> Subject: Re: How to setup multiple JAXRS server endpoints
>
>
>
>
>
> >>>> Hi Jean,
>
>
>
>
>
> >>>> You may run into Swagger JAX-RS scanner limitations, as far as I
>
> >>>> can tell - it checks class annotations for SwaggerDefinition, does
>
> >>>> not traverse the hierarchy [1].
>
>
>
>
>
> >>>> [1]
>
> >>>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagge
>
> >>>> r-
>
> >>>> j
>
> >>>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194
>
>
>
>
>
> >>>> Best Regards,
>
> >>>>     Andriy Redko
>
>
>
>
>
> >>>>>  RE: How to setup multiple JAXRS server endpoints
>
>
>
>
>
> >>>>> Still one question );
>
>
>
>
>
> >>>>> The generated swagger file doesn’t take into account the
>
> >>>>> @SwaggerDefintion on my interface classes?
>
>
>
>
>
> >>>>> As a test I looked at
>
> >>>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m
>
> >>>>> a
>
> >>>>> in/release/samples/jax_rs/description_swagger2_web**
>
> >>>>> and** modified** sample2*
>
> >>>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m
>
> >>>>> a
>
> >>>>> in/release/samples/jax_rs/description_swagger2_web
>
> >>>>> and modified sample2> as follows:
>
>
>
>
>
> >>>>>    @Path("/sample2")
>
>
>
>
>
> >>>>>       @Api(value = "/sample2",authorizations=
>
> >>>>>       {@Authorization(value="bearer")},description = "Sample2
>
> >>>> (modified) JAX-RS
>
> >>>>>       service with Swagger documentation")
>
>
>
>
>
> >>>>>       @SwaggerDefinition(
>
>
>
>
>
> >>>>>               info = @Info(
>
>
>
>
>
> >>>>>                       description = "Sample2 server",
>
>
>
>
>
> >>>>>                       version="1.0",
>
>
>
>
>
> >>>>>                       title = "Test2",
>
>
>
>
>
> >>>>>                       contact = @Contact(name = "J.P. Urkens",email
> = "
>
> >>>>>       *jean-pierre.urkens@devoteam.com* <
>
> >>>> jean-pierre.urkens@devoteam.com>
>
> >>>>>       ")),
>
>
>
>
>
> >>>>>               securityDefinition =
>
> >>>>>       @SecurityDefinition(apiKeyAuthDefinitions=
>
> >>>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name=
> <*%7B@ApiKeyAuthDefinition(key=>
>
> >>>> "A
>
> >>>> u
>
> >>>> thorization",description="Use*
>
> >>>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer
>
> >>>>>       &lt;accessToken&gt;'")})
>
>
>
>
>
> >>>>>       )
>
>
>
>
>
> >>>>>       public class Sample2 {...}
>
>
>
>
>
> >>>>> This correctly generates the ‘securityDefintions’ in the swagger
> file.
>
>
>
>
>
> >>>>> If include the same @SwaggerDefinition and the authorizations on
>
> >>>>> the @Api annotation as above in my interface classes then the
>
> >>>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?
>
>
>
>
>
> >>>>> Any idea what I might be missing?
>
>
>
>
>
> >>>>> Regards,
>
>
>
>
>
> >>>>> J.P.
>
>
>
>
>
> >>>>> -----Original Message-----
>
> >>>>> From: Jean Pierre URKENS <je...@devoteam.com>
>
> >>>>> Sent: dinsdag 23 mei 2023 12:52
>
> >>>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <
>
>
>
> >>>>> Subject: RE: How to setup multiple JAXRS server endpoints
>
>
>
>
>
> >>>>> Hi Andriy,
>
>
>
>
>
> >>>>> I added the parameter usePathBasedConfig=true to the
>
> >>>>> Swagger2Feature bean declarations but still it does generate an
>
> >>>>> empty swagger.yaml for interfaces KmopResources and
>
> >>>>> KmopDienstverlener although I noticed that for these interfaces
>
> >>>>> the
>
> >>>>> @Path() annotation was commented out (as I included it in the
>
> >>>>> server declaration). After providing an empty @Path("")
>
> >>>>> declaration on
>
> >>>> the API interface classes everything worked.
>
>
>
>
>
> >>>>> Thanks for the support.
>
>
>
>
>
> >>>>> -----Original Message-----
>
>
>
>
>
> >>>>> From: Andriy Redko <dr...@gmail.com>
>
>
>
>
>
> >>>>> Sent: dinsdag 23 mei 2023 3:42
>
>
>
>
>
> >>>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>
> >>>>> dev@cxf.apache.org
>
>
>
>
>
> >>>>> Subject: Re: How to setup multiple JAXRS server endpoints
>
>
>
>
>
> >>>>> Hi Jean,
>
>
>
>
>
> >>>>> The main problem to configure Swagger property in your particular
>
> >>>>> case is that the server address is not "known" or "introspectable"
>
> >>>>> for
>
> >>>> Swagger.
>
> >>>>> Intuitively, it has to be set manually using basePath to the,
>
> >>>>> essentially, the server address
>
>
>
>
>
> >>>>> part:
>
>
>
>
>
> >>>>>  - /op/services/accounts
>
>
>
>
>
> >>>>>  - /op/services/resources
>
>
>
>
>
> >>>>>  - /op/services/dienstverlener
>
>
>
>
>
> >>>>> You could read more about other Swagger properties you have asked
> here:
>
> >>>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Int
>
> >>>>> e
>
> >>>>> gration-and-Configuration#configuration-properties
>
>
>
>
>
> >>>>> You definitely need to set usePathBasedConfig to "true" otherwise
>
> >>>>> you will see the same Swagger specs for all servers. We have a
>
> >>>>> sample here which uses 2 jaxrs:server
>
>
>
>
>
> >>>>> instances:
>
> >>>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma
>
> >>>>> i
>
> >>>>> n/release/samples/jax_rs/description_swagger2_web
>
>
>
>
>
> >>>>> Regarding SwaggerUI, I think the value for each of those should be
>
> >>>>> set to,
>
> >>>>> respectively:
>
>
>
>
>
> >>>>>  - /op/services/accounts/swagger.yaml
>
>
>
>
>
> >>>>>  - /op/services/resources/swagger.yaml
>
>
>
>
>
> >>>>>  - /op/services/dienstverlener/swagger.yaml
>
>
>
>
>
> >>>>> I believe this is matching your settings already, except the
>
> >>>>> usePathBasedConfig part. The example referred above could be
>
> >>>>> helpful, my apologies if I missed something, there are quite a lot
>
> >>>>> of questions :-) The fact that the generated Swagger specification
>
> >>>>> is empty is unexpected - it should not happen when JAX-RS
>
> >>>>> resources
>
> >>>> are properly configured.
>
>
>
>
>
> >>>>> Thank you.
>
>
>
>
>
> >>>>> Best Regards,
>
>
>
>
>
> >>>>>     Andriy Redko
>
>
>
>
>
> >>>>>>  RE: How to setup multiple JAXRS server endpoints
>
>
>
>
>
> >>>>>> Hi Andriy,
>
>
>
>
>
> >>>>>> I am not quite understanding how to correctly configure the
>
> >>>>> Swagger2Feature.
>
>
>
>
>
> >>>>>> Referring to the attached cxf-endpoints configuration I (as a
>
> >>>>>> test)
>
>
>
>
>
> >>>>>> created
>
>
>
>
>
> >>>>>> 3 JAXRS server instances:
>
>
>
>
>
> >>>>>> 1.      A* KmopApiServer* server for the*
>
>
>
>
>
> >>>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving
>
>
>
>
>
> >>>>>> requests for URI path:
>
>
>
>
>
> >>>>>>        * <protocol>**//<host:<port>/op/services/accounts*
>
>
>
>
>
> >>>>>>    ‘op’  = root path of the web application
>
>
>
>
>
> >>>>>>             ‘services’ = servlet path of the CXF-servlet
>
>
>
>
>
> >>>>>>       The address of the server is set to ‘/accounts’ and the
>
> >>>>>> @Path(…)
>
>
>
>
>
> >>>>>>       annotation on the interface class was cleared.
>
>
>
>
>
> >>>>>> 2.      A* Kmop**Resources**ApiServer* server for the*
>
> >>>> be.dvtm.aeo.op.*
>
>
>
>
>
> >>>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving
>
>
>
>
>
> >>>>>> requests for URI path:
>
>
>
>
>
> >>>>>>        * <protocol>**//<host:<port>/op/services/**resources*
>
>
>
>
>
> >>>>>> The address of the server is set to ‘/resources’ and the @Path(…)
>
>
>
>
>
> >>>>>> annotation on the interface class was cleared.
>
>
>
>
>
> >>>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*
>
> >>>>> be.dvtm.aeo.op.*
>
>
>
>
>
> >>>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving
>
>
>
>
>
> >>>>>> requests for URI path:
>
>
>
>
>
> >>>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*
>
>
>
>
>
> >>>>>> The address of the server is set to ‘/dienstverlener’ and the
>
>
>
>
>
> >>>>>> @Path(…) annotation on the interface class was cleared.
>
>
>
>
>
> >>>>>> For each of these server instances I’ve set the Swagger2Feature
>
>
>
>
>
> >>>>>> with configuration as indicated in the attached cxf-endpoints.xml.
>
>
>
>
>
> >>>>>> With regard to the configurations for the Swagger2Feature I’ve
>
> >>>>>> the
>
>
>
>
>
> >>>>>> following questions:
>
>
>
>
>
> >>>>>> a)      Referring to *
>
> >>>> https://cxf.apache.org/docs/swagger2feature.html*
>
>
>
>
>
> >>>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you
>
>
>
>
>
> >>>>>> clarify on the following configuration parameters:
>
>
>
>
>
> >>>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘
>
>
>
>
>
> >>>>>> /op/services’) or to the JAX-RS server instance (e.g.
>
>
>
>
>
> >>>>>> ‘/op/services/accounts’) or still something else? Is it used to
>
>
>
>
>
> >>>>>> resolve service classes or is it just for documentation in the
>
> >>>>>> swagger
>
> >>>>> file?
>
>
>
>
>
> >>>>>> *ii.    ** resourcePackage* – the description mentions ‘package
> names’
>
>
>
>
>
> >>>>>> while the default mentions ‘service classes’? Service 2 and 3
>
> >>>>>> above
>
>
>
>
>
> >>>>>> are within the same package (generated from the same yaml
>
>
>
>
>
> >>>>>> specification that included both interfaces).
>
>
>
>
>
> >>>>>> *iii.   ** ig**noreRoutes* – is this taken into account when
>
>
>
>
>
> >>>>>> scanAllResources=false?
>
>
>
>
>
> >>>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter
>
> >>>> value
>
>
>
>
>
> >>>>>> (cf. question ‘a’)?
>
>
>
>
>
> >>>>>> b)      What would be the correct URL to generate a swagger.yaml
>
> >>>>>> file
>
> >>>>> for
>
>
>
>
>
> >>>>>> each of the above interfaces? Initially I called:
>
>
>
>
>
> >>>>>> *i.     **
>
> >>>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*
>
>
>
>
>
> >>>>>> *ii.    **
>
> >>>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*
>
>
>
>
>
> >>>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*
>
>
>
>
>
> >>>>>> *lener/swagger.yaml*
>
>
>
>
>
> >>>>>>    All three requests delivered the same yaml specification,
>
> >>>>>> namely
>
> >>>>> the one
>
>
>
>
>
> >>>>>>       for interface* KmopApiServer*?
>
>
>
>
>
> >>>>>> c)      I tried to debug the processing of the requests under ‘b)’
>
> >>>>>> and
>
> >>>>> this
>
>
>
>
>
> >>>>>> is done by the class JAXRSInterceptor#processRequest where the
>
>
>
>
>
> >>>>>> MessageImpl object for request “ii.” looks like the one attached.
>
>
>
>
>
> >>>>>> It finds 3 resource
>
>
>
>
>
> >>>>>> classes:
>
>
>
>
>
> >>>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl
>
>
>
>
>
> >>>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource
>
>
>
>
>
> >>>>>>       org.apache
>

Request mapping warnings

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
 Request mapping warnings

Still some minor issue related to request mapping.

I notice I am getting warnings like:

   *2023-07-19 13:08:23,022 [T8N1TP1-4] WARN
      (SID=8806F673DEC6B53D9248AF0DD81F6882)
      (org.apache.cxf.jaxrs.model.OperationResourceInfoComparatorBase:102)
- Both
      be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#getDvlById
      and
      be.dvtm.aeo.op.openapi.api.impl.KmopDienstverlenerApiServiceImpl#getDvlById
      are equal candidates for handling the current request which can lead to
      unpredictable results*

Obvious that they are equal candidates because they are the same class. But
what is the cause of this double detection?

Is it because when* JAXRSUtils.**getRootResources*(Message message)  gets
called, I see that it contains 4 entries:

·       (twice) KmopDienstverlenerApiServiceImpl -> my service endpoint

·       io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

·       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService

So twice my service implementation, I wouldn’t know why this is the case?

On my classpath I have set:

·       cxf-rt-rs-service-description-3.5.6.jar                 -> this
handles request for ‘_wadl’

·       cxf-rt-rs-service-description-openapi-v3-3.5.6.jar      -> this
handles request for ‘openapi.[yaml|json]’

·       cxf-rt-rs-service-description-swagger-ui-3.5.6.jar      -> this
handles request for ‘Swagger documentation’

would this be a cause for my service endpoint to appear multiple times?
Aside from that I have no idea what could cause this.

J.P.

-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: donderdag 13 juli 2023 18:24
To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
Subject: Re: How to setup multiple JAXRS server endpoints

Got it, thank you (the Swagger sometimes does surprising things).

Thursday, July 13, 2023, 1:33:07 AM, you wrote:

JPU> The @Parameter annotation seems to be ignored at this level.

JPU> -----Original Message-----

JPU> From: Jean Pierre URKENS <je...@devoteam.com>

JPU> Sent: donderdag 13 juli 2023 7:11

JPU> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'

JPU> <de...@cxf.apache.org>

JPU> Subject: RE: How to setup multiple JAXRS server endpoints

JPU> Yes, SwaggerUI works too!

JPU> I noticed that v2.x of swagger-jaxrs relates to OpenApi v3.1.x

JPU> while my spec is compliant with OpenApi v3.0.x, so I am going to

JPU> stick with v2.1.13 which seems to be that last version for OpenApi
v3.0.x.

JPU> I thought the @Parameter only applied to input parameters ("query",

JPU> "header", "path" or "cookie" parameters), but I'll give it a try.

JPU> J.P.

JPU> -----Original Message-----

JPU> From: Andriy Redko <dr...@gmail.com>

JPU> Sent: woensdag 12 juli 2023 22:16

JPU> To: Jean Pierre URKENS <je...@devoteam.com>;

JPU> dev@cxf.apache.org

JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

JPU> That's awesome, have you got SwaggerUI working as well?

JPU> Yes, you could use 2.2.15 (we already updated to this version, no

JPU> regressions). It seems like the description applies to the whole

JPU> schema (which is the same for both properties), may be you could

JPU> use @Parameter

JPU> instead:

JPU> @Parameter(description="The description I want for prop1")

JPU> Thank you.

JPU> Best Regards,

JPU>     Andriy Redko

>> Hi Andriy,

>> After having migrated everything to "io.swagger.v3.oas.annotations.*"

>> the swagger endpoints for each of my services became active.

>> So far so good, but I do notice that there are discrepancies when

>> annotating models, e.g.:

>>  public class Model1 {

>>   @Schema(description="The description I want for prop1")

>>    private Model2 prop1;

>>   @Schema(description="The description I want for prop2")

>>    private Model2 prop2;

>>   ...

>> }

>> When I generate the openapi.[json|yaml] specification I see that both

>> prop1 and prop2 have a reference to the schema component "Model2"

>> with description ' The description I want for prop2' which is

>> inappropriate for 'prop1'.

>> It is not unlikely to have multiple properties within one Model that

>> are of the same class but are semantically used in a different context.
E.g.

>> something as simple as a ShipmentOrder having two 'Address'

>> properties 'from' and 'to' would result in wrong API documentation.

>> I am aware it has nothing to do with CXF but rather with

>> swagger-jaxrs2-vx.y.z.jar and depending libraries. CXF-3.5.6 has

>> dependency on swagger-jaxrs2-2.1.13.jar. Would it be an issue to

>> replace this dependency with e.g. swagger-jaxrs2-2.2.15.jar (latest

>> stable release according to maven central repo)?

>> J.P.

>> -----Original Message-----

>> From: Jean Pierre URKENS <je...@devoteam.com>

>> Sent: woensdag 12 juli 2023 8:25

>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'

>> <de...@cxf.apache.org>

>> Subject: RE: How to setup multiple JAXRS server endpoints I seem to

>> be mistaken here, the endpoint was loaded (I did a manual HTTP GET

>> test to the endpoint to verify this) although no breakpoints where

>> hit during startup.

>> I am first going to complete the migration to

>> "io.swagger.v3.oas.annotations.*" annotations for all endpoints and

>> then I am going to test again.

>> The application is composed of libraries, some of which use SLF4J but

>> most use LOG4J for logging.

>> J.P.

>> -----Original Message-----

>> From: Andriy Redko <dr...@gmail.com>

>> Sent: woensdag 12 juli 2023 1:13

>> To: Jean Pierre URKENS <je...@devoteam.com>;

>> dev@cxf.apache.org

>> Subject: Re: How to setup multiple JAXRS server endpoints Hi Jean,

>> The

>> OpenApiFeature$Portable#initiliaze(…) should definitely be called

>> (otherwise you shouldn't even see the openapi.json endpoint), so I am

>> not sure why these are not triggering for you.

>>

>> For logging, it seems like you are using SLF4J

>> (org.apache.cxf.common.logging.Slf4jLogger),

>> and also reload4j (aka log4j), why do you need both?

>> Thank you.

>> Best Regards,

>>     Andriy Redko

JPU>>> After some code investigation:

JPU>>> OpenApiFeature implements SwaggerUiSupport and in its

JPU>>> portable#registerSwaggerUiResources(…) method it will call

JPU>>> SwaggerUiSupport#getSwaggerUi(…) which will register the

JPU> SwaggerUiService.

JPU>>> I have put breakpoints on:

JPU>>>    - OpenApiFeature$Portable#initiliaze(…)

JPU>>>    - SwaggerUiService constructor

JPU>>>    - SwaggerUiSupport#getSwaggerUi(…)

JPU>>> but none of them are hit when starting my application?

JPU>>> Although the (spring) logging shows all beans in my

JPU>>> cxf-endpoints.xml have been created?

JPU>>> The *WADL* and *OpenAPI* endpoints to get the specification work.

JPU>>> Even the actual endpoint seems to work although I didn’t hit any

JPU>>> of the breakpoint?

JPU>>> CXF, also doesn’t seem to log a lot, I am hardly getting any log

JPU>>> entries although log level I set to DEBUG.

JPU>>> My logging (except wire message logging) for cxf is setup

JPU>>> correctly (I

JPU>>> think):

JPU>>>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line

JPU>>>    ‘org.apache.cxf.common.logging.Slf4jLogger’

JPU>>>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and

JPU>>>    reload4j-1.2.19.jar are on the classpath

JPU>>>    - the log4j.properties file contains the line:

JPU>>>    ‘log4j.logger.org.apache.cxf=DEBUG’

JPU>>> There are no special instructions mentioned on

JPU>>> https://cxf.apache.org/docs/general-cxf-logging.html so the above

JPU>>> should work (it works for all other packages I use in my
application).

JPU>>> J.P.

JPU>>> *From:* Jean Pierre URKENS <je...@devoteam.com>

JPU>>> *Sent:* dinsdag 11 juli 2023 9:58

JPU>>> *To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <

dev@cxf.apache.org>>>>

JPU>>> *Subject:* RE: How to setup multiple JAXRS server endpoints

JPU>>> Hi Andriy,

JPU>>> As a test I removed all JAX-RS endpoints that use Swagger v2

JPU>>> annotations from my configuration file (see attachment).

JPU>>> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger

JPU>>> v3 annotations, using the OpenApiFeature i.o. Swagger2Feature.

JPU>>> If I run my server with this configuration I only get the

JPU>>> (working)

JPU>>> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint:



JPU>>> So there is some configuration missing to detect/activate the

JPU>>> Swagger endpoint. When I look at the samples that come with the

JPU>>> distribution of CXF (I am using v3.5.6) nothing special seems to

JPU>>> be

JPU> configured to activate this?

JPU>>> Do you have any idea how the SwaggerUiService is picked up when

JPU> loading?

JPU>>> J.P.

JPU>>> -----Original Message-----

JPU>>> From: Andriy Redko <dr...@gmail.com>

JPU>>> Sent: dinsdag 11 juli 2023 3:44

JPU>>> To: Jean Pierre URKENS <je...@devoteam.com>;

JPU>>> dev@cxf.apache.org

JPU>>> Subject: Re: How to setup multiple JAXRS server endpoints

JPU>>> Hi Jean,

JPU>>> I guess you figured one issue, swagger.json -> openapi.json, but

JPU>>> to be honest we have never tested or envisioned the application

JPU>>> that would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same

JPU>>> time, I am afraid this is just not supported. You may get things

JPU>>> back on track when going with OpenAPI 3.0 for all services.

JPU>>> Thank you.

JPU>>> Best Regards,

JPU>>>     Andriy Redko



>>>> Hi Andriy,





>>>> I am trying to trace the difference in handling with another

>>>> application where I’ve got only one CXF service endpoint that uses

>>>> swagger v3 openapi annotations.

>>>> There I see that when handling the Swagger page request (

>>>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json)

>>>> the JAXRSInInterceptor is calling:





>>>> *JAXRSUtils.**getRootResources*(Message message)





>>>> It contains 4 entries:

>>>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint

>>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

>>>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService













>>>> On the application described below with the service ‘oidcsim’ when

>>>> calling the swagger page request

>>>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the

>>>> result of the getRootResources doesn’t contain the

>>>> ClassResourceInfo ‘ SwaggerUiService’. It only contains 3 entries:

>>>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)

>>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource





>>>> The SwaggerUiService is the one that is configured to handle the

JPU>>> ‘api-docs’

>>>> path-request. Since it is missing the request is tried to match

>>>> with the other two resources but fails, hence ‘NOT FOUND’ exception.





>>>> I can’t trace back where these rootResources are set and why the

>>>> SwaggerUiService’ isn’t listed.





>>>> J.P.

>>>> *From:* Jean Pierre URKENS <je...@devoteam.com>

>>>> *Sent:* maandag 10 juli 2023 13:43

>>>> *To:* 'Andriy Redko' <dr...@gmail.com>

>>>> *Subject:* RE: How to setup multiple JAXRS server endpoints





>>>> Andriy,





>>>> I am trying to switch from Swagger v2 to OpenApi v3 annotations

>>>> basically because my starting point is an OpenApi v3.0.7 yaml file

>>>> description and OpenAPI seems to be the way forward.

>>>> For applications where I have only one CXF JAX-RS endpoint exposed

>>>> I had no problems converting. However as soon as there are multiple

>>>> endpoints I run into troubles.





>>>> So, to recall, I've an application exposing 3 JAX-RS endpoints that

>>>> where previously annotated with swagger v2 annotations (i.e.

>>>> package

>>>> io.swagger.annotations.*) which I migrated to

>>>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*).

>>>> In accordance I altered my CXF JAX-RS endpoint configuration from

>>>> (only showing relevant parts, see attachment for full setup):





>>>>                <!-- CXF Swagger2Feature -->

>>>>                <bean id="SwaggerUiConfigOidcApi"

>>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">

>>>>                               <property name="queryConfigEnabled"

>>>>                               <property name="url"

>>>> value="/op/services/oidcsim/swagger.yaml"/>

>>>>                </bean>

>>>>                <bean id="Swagger2FeatureOidcApi"

>>>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">

>>>>                               <property name="basePath"

>>>> value="/op/services/oidcsim"/>

>>>>                               <property name="usePathBasedConfig"

>>>>                               <property name="resourcePackage"

>>>> value="be.dvtm.aeo.op.oidc"/>

>>>>                               <property name="supportSwaggerUi"

>>>>                               <property name="swaggerUiConfig"

>>>> ref="SwaggerUiConfigOidcApi"/>

>>>>                </bean>

>>>>                <jaxrs:server id="OidcProviderApiServer"

>>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">

>>>>                               ....

>>>>                               <jaxrs:features>

>>>>                                              <ref

>>>> bean="Swagger2FeatureOidcApi" />

>>>>                               </jaxrs:features>

>>>>                               ...

>>>>                </jaxrs:server>





>>>> TO:

>>>>                <!-- CXF OpenAPIFeature -->

>>>>                <bean id="OidcSwaggerUiConfig"

>>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">

>>>>                               <property name="queryConfigEnabled"

>>>>                               <property name="url"

>>>> value="openapi.json"/>

>>>>                </bean>

>>>>                <bean id="OidcOpenApiFeature"

>>>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">

>>>>                               <property name="supportSwaggerUi"

>>>>                               <property name="swaggerUiConfig"

>>>> ref="OidcSwaggerUiConfig"/>

>>>>                               <property name="swaggerUiVersion"

>>>>                               <property name="scan" value="false"/>

>>>>                               <property name="useContextBasedConfig"

>>>>                               <property name="resourcePackages"

>>>> value="be.dvtm.aeo.op.oidc"/>

>>>>                </bean>

>>>>                <jaxrs:server id="OidcProviderApiServer"

>>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">

>>>>                               ....

>>>>                               <jaxrs:features>

>>>>                                              <ref

JPU>>> bean="OidcOpenApiFeature"

>>>>                               </jaxrs:features>

>>>>                               ...

>>>>                </jaxrs:server>









>>>> Now when starting my application and navigating to the root part "

>>>> http://localhost:localPort/op/services" I get an overview of all my

>>>> endpoints:





>>>> Now there are 3 RESTful service endpoints setup:

>>>>    1. ‘oidcsim’ which I switched to swagger v3 annotations

>>>>    2. ‘openapi’ currently still swagger v2 annotations

>>>>    3. ‘sdx’ currently still swagger v2 annotations





>>>> all endpoints work except for the ‘swagger endpoint address for the

>>>> oidcsim

>>>> endpoint:

>>>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services

>>>> /o

>>>> i

>>>> dcsim/swagger.json

>>>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*

>>>> endpoint of the oidcsim resource. I am getting an error (the value

>>>> of the ‘url’ query parameter isn’t relevant):





>>>>         “WebApplicationException has been caught, status: 404,

>>>> message: HTTP 404 Not Found”





>>>> When I try (without the ‘/oidcsim’ context):

>>>> http://l-p53-008:8081/op/services/api-docs I get:

>>>>                “No service was found.”





>>>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs

>>>> doesn’t exist, where as the endpoint

>>>> http://l-p53-008:8081/op/services/api-docs does exist but no

>>>> service

JPU>>> description is found?

>>>> Of course my intention is to get working, as previously with the

>>>> swagger v2 setup for which I then specifically added the

>>>> *Swagger2Feature* config

>>>> parameters:

>>>>                               <property name="basePath"

>>>> value="/op/services/oidcsim"/>

>>>>                               <property name="usePathBasedConfig"





>>>> But I don’t find the according configuration options for the

>>>> *OpenApiFeature* class or whether I should configure this in

>>>> another way.





>>>> Any suggestions on this?





>>>> Regards,





>>>> J.P.









>>>> -----Original Message-----

>>>> From: Andriy Redko <dr...@gmail.com>

>>>> Sent: donderdag 25 mei 2023 2:27

>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>>> dev@cxf.apache.org

>>>> Subject: Re: How to setup multiple JAXRS server endpoints





>>>> Hi Jean,





>>>> You may run into Swagger JAX-RS scanner limitations, as far as I

>>>> can tell - it checks class annotations for SwaggerDefinition, does

>>>> not traverse the hierarchy [1].





>>>> [1]

>>>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagge

>>>> r-

>>>> j

>>>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194





>>>> Best Regards,

>>>>     Andriy Redko





>>>>>  RE: How to setup multiple JAXRS server endpoints





>>>>> Still one question );





>>>>> The generated swagger file doesn’t take into account the

>>>>> @SwaggerDefintion on my interface classes?





>>>>> As a test I looked at

>>>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m

>>>>> a

>>>>> in/release/samples/jax_rs/description_swagger2_web**

>>>>> and** modified** sample2*

>>>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/m

>>>>> a

>>>>> in/release/samples/jax_rs/description_swagger2_web

>>>>> and modified sample2> as follows:





>>>>>    @Path("/sample2")





>>>>>       @Api(value = "/sample2",authorizations=

>>>>>       {@Authorization(value="bearer")},description = "Sample2

>>>> (modified) JAX-RS

>>>>>       service with Swagger documentation")





>>>>>       @SwaggerDefinition(





>>>>>               info = @Info(





>>>>>                       description = "Sample2 server",





>>>>>                       version="1.0",





>>>>>                       title = "Test2",





>>>>>                       contact = @Contact(name = "J.P. Urkens",email =
"

>>>>>       *jean-pierre.urkens@devoteam.com* <

>>>> jean-pierre.urkens@devoteam.com>

>>>>>       ")),





>>>>>               securityDefinition =

>>>>>       @SecurityDefinition(apiKeyAuthDefinitions=

>>>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name=
<*{@ApiKeyAuthDefinition(key=>

>>>> "A

>>>> u

>>>> thorization",description="Use*

>>>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer

>>>>>       &lt;accessToken&gt;'")})





>>>>>       )





>>>>>       public class Sample2 {...}





>>>>> This correctly generates the ‘securityDefintions’ in the swagger file.





>>>>> If include the same @SwaggerDefinition and the authorizations on

>>>>> the @Api annotation as above in my interface classes then the

>>>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?





>>>>> Any idea what I might be missing?





>>>>> Regards,





>>>>> J.P.





>>>>> -----Original Message-----

>>>>> From: Jean Pierre URKENS <je...@devoteam.com>

>>>>> Sent: dinsdag 23 mei 2023 12:52

>>>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <



>>>>> Subject: RE: How to setup multiple JAXRS server endpoints





>>>>> Hi Andriy,





>>>>> I added the parameter usePathBasedConfig=true to the

>>>>> Swagger2Feature bean declarations but still it does generate an

>>>>> empty swagger.yaml for interfaces KmopResources and

>>>>> KmopDienstverlener although I noticed that for these interfaces

>>>>> the

>>>>> @Path() annotation was commented out (as I included it in the

>>>>> server declaration). After providing an empty @Path("")

>>>>> declaration on

>>>> the API interface classes everything worked.





>>>>> Thanks for the support.





>>>>> -----Original Message-----





>>>>> From: Andriy Redko <dr...@gmail.com>





>>>>> Sent: dinsdag 23 mei 2023 3:42





>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>>>> dev@cxf.apache.org





>>>>> Subject: Re: How to setup multiple JAXRS server endpoints





>>>>> Hi Jean,





>>>>> The main problem to configure Swagger property in your particular

>>>>> case is that the server address is not "known" or "introspectable"

>>>>> for

>>>> Swagger.

>>>>> Intuitively, it has to be set manually using basePath to the,

>>>>> essentially, the server address





>>>>> part:





>>>>>  - /op/services/accounts





>>>>>  - /op/services/resources





>>>>>  - /op/services/dienstverlener





>>>>> You could read more about other Swagger properties you have asked
here:

>>>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Int

>>>>> e

>>>>> gration-and-Configuration#configuration-properties





>>>>> You definitely need to set usePathBasedConfig to "true" otherwise

>>>>> you will see the same Swagger specs for all servers. We have a

>>>>> sample here which uses 2 jaxrs:server





>>>>> instances:

>>>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma

>>>>> i

>>>>> n/release/samples/jax_rs/description_swagger2_web





>>>>> Regarding SwaggerUI, I think the value for each of those should be

>>>>> set to,

>>>>> respectively:





>>>>>  - /op/services/accounts/swagger.yaml





>>>>>  - /op/services/resources/swagger.yaml





>>>>>  - /op/services/dienstverlener/swagger.yaml





>>>>> I believe this is matching your settings already, except the

>>>>> usePathBasedConfig part. The example referred above could be

>>>>> helpful, my apologies if I missed something, there are quite a lot

>>>>> of questions :-) The fact that the generated Swagger specification

>>>>> is empty is unexpected - it should not happen when JAX-RS

>>>>> resources

>>>> are properly configured.





>>>>> Thank you.





>>>>> Best Regards,





>>>>>     Andriy Redko





>>>>>>  RE: How to setup multiple JAXRS server endpoints





>>>>>> Hi Andriy,





>>>>>> I am not quite understanding how to correctly configure the

>>>>> Swagger2Feature.





>>>>>> Referring to the attached cxf-endpoints configuration I (as a

>>>>>> test)





>>>>>> created





>>>>>> 3 JAXRS server instances:





>>>>>> 1.      A* KmopApiServer* server for the*





>>>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving





>>>>>> requests for URI path:





>>>>>>        * <protocol>**//<host:<port>/op/services/accounts*





>>>>>>    ‘op’  = root path of the web application





>>>>>>             ‘services’ = servlet path of the CXF-servlet





>>>>>>       The address of the server is set to ‘/accounts’ and the

>>>>>> @Path(…)





>>>>>>       annotation on the interface class was cleared.





>>>>>> 2.      A* Kmop**Resources**ApiServer* server for the*

>>>> be.dvtm.aeo.op.*





>>>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving





>>>>>> requests for URI path:





>>>>>>        * <protocol>**//<host:<port>/op/services/**resources*





>>>>>> The address of the server is set to ‘/resources’ and the @Path(…)





>>>>>> annotation on the interface class was cleared.





>>>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*

>>>>> be.dvtm.aeo.op.*





>>>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving





>>>>>> requests for URI path:





>>>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*





>>>>>> The address of the server is set to ‘/dienstverlener’ and the





>>>>>> @Path(…) annotation on the interface class was cleared.





>>>>>> For each of these server instances I’ve set the Swagger2Feature





>>>>>> with configuration as indicated in the attached cxf-endpoints.xml.





>>>>>> With regard to the configurations for the Swagger2Feature I’ve

>>>>>> the





>>>>>> following questions:





>>>>>> a)      Referring to *

>>>> https://cxf.apache.org/docs/swagger2feature.html*





>>>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you





>>>>>> clarify on the following configuration parameters:





>>>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘





>>>>>> /op/services’) or to the JAX-RS server instance (e.g.





>>>>>> ‘/op/services/accounts’) or still something else? Is it used to





>>>>>> resolve service classes or is it just for documentation in the

>>>>>> swagger

>>>>> file?





>>>>>> *ii.    ** resourcePackage* – the description mentions ‘package
names’





>>>>>> while the default mentions ‘service classes’? Service 2 and 3

>>>>>> above





>>>>>> are within the same package (generated from the same yaml





>>>>>> specification that included both interfaces).





>>>>>> *iii.   ** ig**noreRoutes* – is this taken into account when





>>>>>> scanAllResources=false?





>>>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter

>>>> value





>>>>>> (cf. question ‘a’)?





>>>>>> b)      What would be the correct URL to generate a swagger.yaml

>>>>>> file

>>>>> for





>>>>>> each of the above interfaces? Initially I called:





>>>>>> *i.     **

>>>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*





>>>>>> *ii.    **

>>>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*





>>>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*





>>>>>> *lener/swagger.yaml*





>>>>>>    All three requests delivered the same yaml specification,

>>>>>> namely

>>>>> the one





>>>>>>       for interface* KmopApiServer*?





>>>>>> c)      I tried to debug the processing of the requests under ‘b)’

>>>>>> and

>>>>> this





>>>>>> is done by the class JAXRSInterceptor#processRequest where the





>>>>>> MessageImpl object for request “ii.” looks like the one attached.





>>>>>> It finds 3 resource





>>>>>> classes:





>>>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl





>>>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource





>>>>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService





>>>>>> è       It matches the request to resource*

>>>>> Swagger2ApiListingResource* with





>>>>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*





>>>>>> process(…)* method.





>>>>>> è       Here it seems to go wrong. It generates a

>>>> SwaggerContextService





>>>>>> having basePath=/op/services/resources/,swaggerConfig=null,





>>>>>> usePathBasedConfig=null and then calls





>>>>>> SwaggerContextService.getSwagger()





>>>>>> which returns the Swagger definition for interface KmopApiServer?





>>>>>> It looks like it caches generated swagger definitions based on a





>>>>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the





>>>>>> same for all 3 interfaces as usePathBasedConfig=null





>>>>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig

>>>>>> is





>>>>>> derived from the ServletConfig parameter





>>>>>> ‘swagger.use.path.based.config’.* So should this be set on the





>>>>>> declaration of the CXFServlet** in web.xml?*





>>>>>> è       Actually the SwaggerConfig, the JaxrsScanner and the

>>>>>> generated

>>>>> Swagger





>>>>>> are cached using keys like





>>>>>> ‘swagger.config.id.[default|baseUriPath]’, ‘





>>>>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’

>>>>> is only done when usePathBasedconfig=true.





>>>>>> è       If I patch this to true then configIdKey=’





>>>>>> swagger.config.id./op/services/resources/’ and no swagger entry

>>>>>> is





>>>>>> cached for this key so it will generate a new one. Again by





>>>>>> patching





>>>>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tr

>>>>>> u

>>>>>> e





>>>>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”





>>>>>> è       Again Scanners are cached and if usePathBasedConfig=null it

>>>>> will use





>>>>>> the one cached under  ‘swagger.scanner.id.default’ and this again





>>>>>> returns the swagger definition for the KmopApiService interface.





>>>>>> è       So patching usePathBasedConfig=true will return a new one





>>>>>> (DefaultJaxrsScanner). The classes to scan for in this new

>>>>>> scanner





>>>>>> are ‘

>>>>>> be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘





>>>>>> which is correct. It will generate a new (but empty) Swagger object.





>>>>>> è       Next Swagger2ApiListingResource will call the





>>>>>> customizer.customize(s), which still isn’t putting anything new

>>>>>> in





>>>>>> the Swagger object. Should it or should the next step do this?





>>>>>> è       Next BaseApiListingResource#getListing(…) is called which on

>>>>> its





>>>>>> turn calls getListingYamlResponse(..)





>>>>>> è       The final result is a swagger.yaml document with following

>>>>> content:





>>>>>>    swagger: "2.0"





>>>>>>       info:





>>>>>>         license:





>>>>>>           name: "Apache 2.0 License"





>>>>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html





>>>>>>       basePath: "/op/services/resources"





>>>>>>        So basically an empty swagger file.





>>>>>> d)      The usePathBasedConfig is derived from the ServletConfig

>>>>> parameter ‘





>>>>>> swagger.use.path.based.config’. Without this parameter set to

>>>>>> true





>>>>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger





>>>>>> object.* So should this be set on the declaration of the





>>>>>> CXFServlet** in web.xml?*





>>>>>> The majority in this processing happens in the library





>>>>>> swagger-jaxrs-v1.6.10 which is included as a dependency on

>>>>> cxf-rt-rs-service-description-swagger.





>>>>>> Even if I patch usePathBasedConfig=true about everywhere where I





>>>>>> met this it still doesn’t generate a correct swagger.yaml. Am I





>>>>>> still missing some configuration parameter?





>>>>>> Any suggestions on how to resolve this would be welcome.





>>>>>> Regards,





>>>>>> J.P. Urkens









































>>>>>> <<...>> <<...>>





>>>>>> -----Original Message-----





>>>>>> From: Andriy Redko <dr...@gmail.com>





>>>>>> Sent: maandag 8 mei 2023 23:15





>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev





>>>>>> List <











>>>>>> Subject: Re: How to setup multiple JAXRS server endpoints





>>>>>> Hi Jean,





>>>>>> Indeed the way you would like to do that is somewhat tricky.





>>>>>>> So I tried to keep the @Path declaration on the interface

>>>>>>> classes

>>>>>>> but





>>>>>> changed them to @Path(“”). That does seems to work except the





>>>>>> swagger stuff no longer correctly works.





>>>>>> This is one of the possible options but OpenAPI/Swagger gets





>>>>>> confused for a





>>>>>> reason: the path is now implicit (not in the spec).





>>>>>> So how about this option:





>>>>>>  - use only one JAX-RS server (address "/")





>>>>>>  - host both resources but use @Path("accounts") and





>>>>>> @Path("resources") on them respectively









>>>>>> I see that for @Path("accounts") you need to apply the





>>>>>> "kmopApiAuthorizationFilter", that could be done using





>>>>>> DynamicFeature [1], [2]. If this is not the option and you would





>>>>>> prefer to use 2 separate JAX-RS servers, you may need to provide





>>>>>> your own instance of Swagger2Customizer [3], [4] which allows to





>>>>>> transform the OpenAPI/Swagger on the fly. Please let me know if

>>>>>> that

>>>>> would it work for you, thank you.





>>>>>> [1]





>>>>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynami

>>>>>> c

>>>>>> F





>>>>>> eature.html





>>>>>> [2]





>>>>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-bor

>>>>>> n

>>>>>> -





>>>>>> equal.html





>>>>>> [3]





>>>>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagge

>>>>>> r

>>>>>> /





>>>>>> Swagger2Customizer.html





>>>>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has





>>>>>> customizer





>>>>>> property)









>>>>>> Best Regards,





>>>>>>     Andriy Redko





>>>>>>> Hi Andriy,





>>>>>>> I am again getting into trouble with server endpoint declarations.





>>>>>>> Now





>>>>>> because I am adding additional JAX-RS endpoints.





>>>>>>> The issue is with:





>>>>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration

>>>>>>> in





>>>>>> combination with





>>>>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the

>>>>>>> web.xml





>>>>>> in combination with





>>>>>>> 3.      The @Path declaration in the interface class in combination

>>>>>>> with





>>>>>>> 4.      The @Path declaration on the interface method in

>>>>>>> combination

>>>> with





>>>>>>> So what I had is that my web application deployed under baseUlr 'op'





>>>>>>> had





>>>>>> one JAXRS server endpoint with declarations like:





>>>>>>> 1.      <jaxrs:server id="restServer"





>>>>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">





>>>>>>> 2.      <url-pattern>/services/*</url-pattern>





>>>>>>> 3.      @Path("accounts") on the public interface class





>>>>>>> 4.      @Path("/{authorisationId}/customerFund") on the

>>>>>>> customerFund





>>>>>> interface method





>>>>>>> A valid API call would thus be e.g.:





>>>>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}

>>>>>>> /c

>>>>>>> u

>>>>>>> s

>>>>>>> t





>>>>>>> o





>>>>>>> merFund





>>>>>>> And this works correctly.





>>>>>>> We're now introducing additional JAX-RS service endpoints and

>>>>>>> now I





>>>>>>> am





>>>>>> running into problems. This second endpoint was declared with:





>>>>>>> 1.      <jaxrs:server id="resourceServer"





>>>>>> basePackages="be.dvtm.aeo.op.resources" address="/">





>>>>>>> 2.      <url-pattern>/services/*</url-pattern>





>>>>>>> 3.      @Path("resources") on the public interface class





>>>>>>> 4.      @Path("/NACE") on the NACE interface method





>>>>>>> So here a valid API call woud be:





>>>>>> https://<hostname>:<port>/op/services/resources/NACE.





>>>>>>> The problem is that I can not declare two <jaxrs:server> entries

>>>>>>> with





>>>>>>> the





>>>>>> same ‘address’ as it throws the exception:





>>>>>>> Caused by:

>>>>>>> org.apache.cxf.service.factory.ServiceConstructionException:





>>>>>> There is an endpoint already running on /.





>>>>>>>  So I tried changing the addresses to:





>>>>>>> ·       address=”accounts” for the restServer





>>>>>>> ·       address=”resources” for the resourceServer





>>>>>>> But to keep the API-call URLs the same I removed the @Path





>>>>>>> declaration on





>>>>>> the interface classes. By doing so the <jaxrs:server> bean





>>>>>> declarations no longer loads successfully.





>>>>>>> So I tried to keep the @Path declaration on the interface

>>>>>>> classes

>>>>>>> but





>>>>>> changed them to @Path(“”). That does seems to work except the





>>>>>> swagger stuff no longer correctly works.





>>>>>>> So what is the decent way to setup multiple JAX-RS server

>>>>>>> endpoints





>>>>>>> where





>>>>>> each server has its own configuration regarding supported features:





>>>>>>> ·       own validation





>>>>>>> ·       own object and exception mappings





>>>>>>> ·       own swagger file generation





>>>>>>> ·       own logging (in separate file if possible)





>>>>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in





>>>>>>> cooperation





>>>>>> with swager-ui v4.5.0.





>>>>>>> Below the declarations of my endpoints <<...>> Thanks for any
advice.





>>>>>>> Regards,





>>>>>>> J.P. Urkens





>>>>>>> -----Original Message-----





>>>>>>> From: Andriy Redko <dr...@gmail.com>





>>>>>>> Sent: zaterdag 18 juni 2022 1:12





>>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;





>>>>>>> issues@cxf.apache.org; dev@cxf.apache.org





>>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi

>>>>>>> Jean,





>>>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'





>>>>>>> Correct, so in the relative form like address="/<something>",

>>>>>>> the





>>>>>>> JAX-RS





>>>>>> endpoint path would be:





>>>>>>>     <baseUrl>/<servlet path





mapping>>>>>>>>/<address>/[@ApplicationPath]/[@Path]





>>>>>>> The @ApplicationPath is optional in this case.





>>>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'





>>>>>>> The JAX-WS is very different from JAX-RS, essentially the action





>>>>>>> comes





>>>>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/





>>>>>> (@Path / @ApplicationPath are not relevant there).





>>>>>>>> Question: Because now address="/" is set for the jaxrs:server

>>>>>>>> will





>>>>>>>> it





>>>>>>>> also inspect requests targeted for the jaxws service as those





>>>>>>>> requests have start with the same path '/<basePath>/services/...





>>>>>>> This is a good question, I have not done it myself but I think

>>>>>>> it





>>>>>>> should





>>>>>> work:





>>>>>>> the servlet dispatches according to registered services, in this





>>>>>>> regard





>>>>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?

>>>>> Thank you.





>>>>>>> Best Regards,





>>>>>>>     Andriy Redko





>>>>>>>> Hi Andriy,





>>>>>>>> Using address="/" seems to work but still I don't understand

>>>>>>>> how

>>>>>>>> the





>>>>>>>> following work together:





>>>>>>>>  - path specification in servlet mapping for the CXF servlet





>>>>>>>> (org.apache.cxf.transport.servlet.CXFServlet)





>>>>>>>>  - the 'address' attribute on the jaxrs:server bean declaration





>>>>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on

>>>>>>>> the





>>>>>>>> service API description Say I've two services with (relateive

>>>>>>>> to

>>>>>>>> the





>>>>>>>> host) url's:





>>>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'





>>>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'





>>>>>>>> How do I configure above 3 aspects? Currently I have (working):





>>>>>>>> 1.for the jaxrs:server endpoint:





>>>>>>>>         - servlet path mapping: '/services/*'





>>>>>>>>                - jaxrs-server address attribute: address="/"





>>>>>>>>                - @Path annotation: @Path("service1") 2.For the

>>>>>>>> jaxws





>>>>>>>> service endpoint:





>>>>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS





>>>>>>>> requests are handleb by the same CXF servle)





>>>>>>>>                - jaxws:endpoint server address attribute:





>>>>>>>> address="/service2"





>>>>>>>>                - @WebService(name="service2") A correct request

>>>>>>>> for





>>>>>>>> '1' would be '/basePath>/services/service1/<ID>'.





>>>>>>>> A correct request for '2' would be '/basePath>/services/service2'.





>>>>>>>> The jaxrs/jaxws configuration behavior seem to differ with

>>>>>>>> respect

>>>>>>>> to:





>>>>>>>>         - the server address attribute





>>>>>>>>         - The API annotation (@Path or @Webservice) The JAXWS

>>>>>>>> server





>>>>>>>> address attribute doesn't seem to interfere with the

>>>>>>>> @Webservice





>>>>>>>> annotation. While the jaxrs server address attribute does seem

>>>>>>>> to





>>>>>>>> interfere with the @Path annotation. I would have expected the

>>>>>>>> jaxrs





>>>>>>>> server aspects to be configured as:





>>>>>>>>         - servlet path mapping: '/services/*'





>>>>>>>>                - jaxrs-server address attribute:
address="/service1"





>>>>>>>>                - @Path annotation: @Path("service1") but then a





>>>>>>>> valid





>>>>>>>> request would be





>>>>>>>>> /services/service1/service1/<ID>'.





>>>>>>>> For both the 'address' attribute is relative to the servlet path.





>>>>>>>> The @Path Javadoc mentions that this path is relative to the





>>>>>>>> ApplicationPath which thus seems to be relative to the

>>>>>>>> jaxrs-server





>>>>>>>> address attribute. As for @Webservice it doesnn't seem to be





>>>>>>>> url-path





>>>>>> related.





>>>>>>>> Question: Because now address="/" is set for the jaxrs:server

>>>>>>>> will





>>>>>>>> it





>>>>>>>> also inspect requests targeted for the jaxws service as those





>>>>>>>> requests have start with the same path '/<basePath>/services/...'.





>>>>>>>> Albeit somewhat confusing.





>>>>>>>> J.P.





>>>>>>>> -----Original Message-----





>>>>>>>> From: Andriy Redko <dr...@gmail.com>





>>>>>>>> Sent: dinsdag 14 juni 2022 1:08





>>>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;





>>>>>>>> issues@cxf.apache.org; dev@cxf.apache.org





>>>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi

>>>>>>>> Jean,





>>>>>>>> Indeed, the jaxrs:server does not expect address to be omitted,

>>>>>>>> you





>>>>>>>> could use the "/" (and I believe an empty string would also

>>>>>>>> make

>>>>>>>> it):





>>>>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...





>>>>>>>> </jaxrs:server>





>>>>>>>> Thank you.





>>>>>>>> Hope it helps.





>>>>>>>> Best Regards,





>>>>>>>>     Andriy Redko





>>>>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean





>>>>>>>>> declarations





>>>>>>>>> like:





>>>>>>>>>      <jaxrs:server id="restServer" basePackages="xxx">





>>>>>>>>>            <jaxrs:serviceBeans>





>>>>>>>>>                 <ref bean="TestApi" />





>>>>>>>>>            </jaxrs:serviceBeans>





>>>>>>>>>            <jaxrs:providers>





>>>>>>>>>                 <…/>





>>>>>>>>>            </jaxrs:providers>





>>>>>>>>>            <jaxrs:features>





>>>>>>>>>                 <… />





>>>>>>>>>            </jaxrs:features>





>>>>>>>>>            <jaxrs:inInterceptors>





>>>>>>>>>                 <… />





>>>>>>>>>            </jaxrs:inInterceptors>





>>>>>>>>>            <jaxrs:outInterceptors>*





>>>>>>>>>                 <**…**/>*





>>>>>>>>>            </jaxrs:outInterceptors>*





>>>>>>>>>      </jaxrs:server>









>>>>>>>>> Here my “TestApi” bean interface is declared like:





>>>>>>>>>       @Path("accounts")





>>>>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)





>>>>>>>>>        @Produces(MediaType.*APPLICATION_JSON*)





>>>>>>>>>        public interface TestApi {





>>>>>>>>>          …





>>>>>>>>>        }





>>>>>>>>> And CXF is triggered via a servlet configuration like:





>>>>>>>>>      <servlet>





>>>>>>>>>              <display-name>CXF Servlet</display-name>





>>>>>>>>>              <servlet-name>CXFServlet</servlet-name>





>>>>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</se

>>>>>>>>> rv

>>>>>>>>> l

>>>>>>>>> e





>>>>>>>>> t











>>>>>>>>>        </servlet>





>>>>>>>>>        <servlet-mapping>





>>>>>>>>>              <servlet-name>CXFServlet</servlet-name>





>>>>>>>>>              <url-pattern>/services/*</url-pattern>





>>>>>>>>>        </servlet-mapping>









>>>>>>>>> Because I’ve got the @Path declaration on the interface type

>>>>>>>>> I’ve





>>>>>>>>> omitted





>>>>>>>>> the address=”accounts” attribute on the jaxrs:server

>>>>>>>>> declaration





>>>>>>>>> since otherwise





>>>>>>>>> I noticed that the server would be listening to





>>>>>>>>> /basepath/services/ accounts/accounts/…).





>>>>>>>>> Now this configuration works perfectly, only when shutting

>>>>>>>>> down





>>>>>>>>> the application server cxf calls





>>>>>>>>>         ServerImpl#destroy()





>>>>>>>>> which delegates (via Obeservable) to





>>>>>>>>> AbstractHTTPDestination#deactivate()





>>>>>>>>> which calls





>>>>>>>>> registry.removeDestination(path).





>>>>>>>>> This path is null (no ‘address’ specified on jaxrs:server





>>>>>>>>> declaration) and results in a NPE on the registry Map.





>>>>>>>>> This causes an unclean shutdown of my server.





>>>>>>>>> Is this an error in cxf or is my jaxrs:server configured

>>>>>>>>> incorrectly?





>>>>>>>>> How does the ‘address’ attribute on the jaxrs:server

>>>>>>>>> declaration





>>>>>>>>> correctly interact with the @Path parameter on the API interface?





>>>>>> <<...>>

Re: How to setup multiple JAXRS server endpoints

Posted by Andriy Redko <dr...@gmail.com>.
Got it, thank you (the Swagger sometimes does surprising things).

Thursday, July 13, 2023, 1:33:07 AM, you wrote:

JPU> The @Parameter annotation seems to be ignored at this level.

JPU> -----Original Message-----
JPU> From: Jean Pierre URKENS <je...@devoteam.com>
JPU> Sent: donderdag 13 juli 2023 7:11
JPU> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'
JPU> <de...@cxf.apache.org>
JPU> Subject: RE: How to setup multiple JAXRS server endpoints

JPU> Yes, SwaggerUI works too!
JPU> I noticed that v2.x of swagger-jaxrs relates to OpenApi v3.1.x while my spec
JPU> is compliant with OpenApi v3.0.x, so I am going to stick with v2.1.13 which
JPU> seems to be that last version for OpenApi v3.0.x.

JPU> I thought the @Parameter only applied to input parameters ("query",
JPU> "header", "path" or "cookie" parameters), but I'll give it a try.

JPU> J.P.

JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: woensdag 12 juli 2023 22:16
JPU> To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

JPU> That's awesome, have you got SwaggerUI working as well?

JPU> Yes, you could use 2.2.15 (we already updated to this version, no
JPU> regressions). It seems like the description applies to the whole schema
JPU> (which is the same for both properties), may be you could use @Parameter
JPU> instead:

JPU> @Parameter(description="The description I want for prop1")

JPU> Thank you.

JPU> Best Regards,
JPU>     Andriy Redko

>> Hi Andriy,
>> After having migrated everything to "io.swagger.v3.oas.annotations.*" the
>> swagger endpoints for each of my services became active.
>> So far so good, but I do notice that there are discrepancies when
>> annotating models, e.g.:
>>  public class Model1 {
>>   @Schema(description="The description I want for prop1")
>>    private Model2 prop1;
>>   @Schema(description="The description I want for prop2")
>>    private Model2 prop2;
>>   ...
>> }
>> When I generate the openapi.[json|yaml] specification I see that both
>> prop1 and prop2 have a reference to the schema component "Model2" with
>> description ' The description I want for prop2' which is inappropriate for
>> 'prop1'.
>> It is not unlikely to have multiple properties within one Model that are
>> of the same class but are semantically used in a different context. E.g.
>> something as simple as a ShipmentOrder having two 'Address' properties
>> 'from' and 'to' would result in wrong API documentation.
>> I am aware it has nothing to do with CXF but rather with
>> swagger-jaxrs2-vx.y.z.jar and depending libraries. CXF-3.5.6 has
>> dependency on swagger-jaxrs2-2.1.13.jar. Would it be an issue to replace
>> this dependency with e.g. swagger-jaxrs2-2.2.15.jar (latest stable release
>> according to maven central repo)?
>> J.P.
>> -----Original Message-----
>> From: Jean Pierre URKENS <je...@devoteam.com>
>> Sent: woensdag 12 juli 2023 8:25
>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'
>> <de...@cxf.apache.org>
>> Subject: RE: How to setup multiple JAXRS server endpoints I seem to be
>> mistaken here, the endpoint was loaded (I did a manual HTTP GET test to
>> the endpoint to verify this) although no breakpoints where hit during
>> startup.
>> I am first going to complete the migration to
>> "io.swagger.v3.oas.annotations.*" annotations for all endpoints and then I
>> am going to test again.
>> The application is composed of libraries, some of which use SLF4J but most
>> use LOG4J for logging.
>> J.P.

>> -----Original Message-----
>> From: Andriy Redko <dr...@gmail.com>
>> Sent: woensdag 12 juli 2023 1:13
>> To: Jean Pierre URKENS <je...@devoteam.com>;
>> dev@cxf.apache.org
>> Subject: Re: How to setup multiple JAXRS server endpoints Hi Jean, The
>> OpenApiFeature$Portable#initiliaze(…) should definitely be called
>> (otherwise you shouldn't even see the openapi.json endpoint), so I am not
>> sure why these are not triggering for you.
>>
>> For logging, it seems like you are using SLF4J
>> (org.apache.cxf.common.logging.Slf4jLogger),
>> and also reload4j (aka log4j), why do you need both?
>> Thank you.
>> Best Regards,
>>     Andriy Redko
JPU>>> After some code investigation:


JPU>>> OpenApiFeature implements SwaggerUiSupport and in its
JPU>>> portable#registerSwaggerUiResources(…) method it will call
JPU>>> SwaggerUiSupport#getSwaggerUi(…) which will register the
JPU> SwaggerUiService.


JPU>>> I have put breakpoints on:
JPU>>>    - OpenApiFeature$Portable#initiliaze(…)
JPU>>>    - SwaggerUiService constructor
JPU>>>    - SwaggerUiSupport#getSwaggerUi(…)


JPU>>> but none of them are hit when starting my application?


JPU>>> Although the (spring) logging shows all beans in my
JPU>>> cxf-endpoints.xml have been created?
JPU>>> The *WADL* and *OpenAPI* endpoints to get the specification work.
JPU>>> Even the actual endpoint seems to work although I didn’t hit any
JPU>>> of the breakpoint?


JPU>>> CXF, also doesn’t seem to log a lot, I am hardly getting any log
JPU>>> entries although log level I set to DEBUG.
JPU>>> My logging (except wire message logging) for cxf is setup
JPU>>> correctly (I
JPU>>> think):
JPU>>>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line
JPU>>>    ‘org.apache.cxf.common.logging.Slf4jLogger’
JPU>>>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and
JPU>>>    reload4j-1.2.19.jar are on the classpath
JPU>>>    - the log4j.properties file contains the line:
JPU>>>    ‘log4j.logger.org.apache.cxf=DEBUG’


JPU>>> There are no special instructions mentioned on
JPU>>> https://cxf.apache.org/docs/general-cxf-logging.html so the above
JPU>>> should work (it works for all other packages I use in my application).


JPU>>> J.P.
JPU>>> *From:* Jean Pierre URKENS <je...@devoteam.com>
JPU>>> *Sent:* dinsdag 11 juli 2023 9:58
JPU>>> *To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <
dev@cxf.apache.org>>>>
JPU>>> *Subject:* RE: How to setup multiple JAXRS server endpoints


JPU>>> Hi Andriy,


JPU>>> As a test I removed all JAX-RS endpoints that use Swagger v2
JPU>>> annotations from my configuration file (see attachment).
JPU>>> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger v3
JPU>>> annotations, using the OpenApiFeature i.o. Swagger2Feature.
JPU>>> If I run my server with this configuration I only get the (working)
JPU>>> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint:




JPU>>> So there is some configuration missing to detect/activate the
JPU>>> Swagger endpoint. When I look at the samples that come with the
JPU>>> distribution of CXF (I am using v3.5.6) nothing special seems to be
JPU> configured to activate this?
JPU>>> Do you have any idea how the SwaggerUiService is picked up when
JPU> loading?


JPU>>> J.P.


JPU>>> -----Original Message-----
JPU>>> From: Andriy Redko <dr...@gmail.com>
JPU>>> Sent: dinsdag 11 juli 2023 3:44
JPU>>> To: Jean Pierre URKENS <je...@devoteam.com>;
JPU>>> dev@cxf.apache.org
JPU>>> Subject: Re: How to setup multiple JAXRS server endpoints


JPU>>> Hi Jean,


JPU>>> I guess you figured one issue, swagger.json -> openapi.json, but to
JPU>>> be honest we have never tested or envisioned the application that
JPU>>> would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same time, I
JPU>>> am afraid this is just not supported. You may get things back on
JPU>>> track when going with OpenAPI 3.0 for all services.


JPU>>> Thank you.


JPU>>> Best Regards,
JPU>>>     Andriy Redko




>>>> Hi Andriy,






>>>> I am trying to trace the difference in handling with another
>>>> application where I’ve got only one CXF service endpoint that uses
>>>> swagger v3 openapi annotations.


>>>> There I see that when handling the Swagger page request (
>>>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json) the
>>>> JAXRSInInterceptor is calling:






>>>> *JAXRSUtils.**getRootResources*(Message message)






>>>> It contains 4 entries:


>>>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint
>>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource
>>>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService














>>>> On the application described below with the service ‘oidcsim’ when
>>>> calling the swagger page request
>>>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the
>>>> result of the getRootResources doesn’t contain the ClassResourceInfo
>>>> ‘
>>>> SwaggerUiService’. It only contains 3 entries:


>>>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)
>>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource






>>>> The SwaggerUiService is the one that is configured to handle the
JPU>>> ‘api-docs’
>>>> path-request. Since it is missing the request is tried to match with
>>>> the other two resources but fails, hence ‘NOT FOUND’ exception.






>>>> I can’t trace back where these rootResources are set and why the
>>>> SwaggerUiService’ isn’t listed.






>>>> J.P.


>>>> *From:* Jean Pierre URKENS <je...@devoteam.com>
>>>> *Sent:* maandag 10 juli 2023 13:43
>>>> *To:* 'Andriy Redko' <dr...@gmail.com>
>>>> *Subject:* RE: How to setup multiple JAXRS server endpoints






>>>> Andriy,






>>>> I am trying to switch from Swagger v2 to OpenApi v3 annotations
>>>> basically because my starting point is an OpenApi v3.0.7 yaml file
>>>> description and OpenAPI seems to be the way forward.


>>>> For applications where I have only one CXF JAX-RS endpoint exposed I
>>>> had no problems converting. However as soon as there are multiple
>>>> endpoints I run into troubles.






>>>> So, to recall, I've an application exposing 3 JAX-RS endpoints that
>>>> where previously annotated with swagger v2 annotations (i.e. package
>>>> io.swagger.annotations.*) which I migrated to


>>>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*). In
>>>> accordance I altered my CXF JAX-RS endpoint configuration from (only
>>>> showing relevant parts, see attachment for full setup):






>>>>                <!-- CXF Swagger2Feature -->


>>>>                <bean id="SwaggerUiConfigOidcApi"
>>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">


>>>>                               <property name="queryConfigEnabled"


>>>>                               <property name="url"
>>>> value="/op/services/oidcsim/swagger.yaml"/>


>>>>                </bean>


>>>>                <bean id="Swagger2FeatureOidcApi"
>>>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">


>>>>                               <property name="basePath"
>>>> value="/op/services/oidcsim"/>


>>>>                               <property name="usePathBasedConfig"


>>>>                               <property name="resourcePackage"
>>>> value="be.dvtm.aeo.op.oidc"/>


>>>>                               <property name="supportSwaggerUi"


>>>>                               <property name="swaggerUiConfig"
>>>> ref="SwaggerUiConfigOidcApi"/>


>>>>                </bean>


>>>>                <jaxrs:server id="OidcProviderApiServer"
>>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">


>>>>                               ....


>>>>                               <jaxrs:features>


>>>>                                              <ref
>>>> bean="Swagger2FeatureOidcApi" />


>>>>                               </jaxrs:features>


>>>>                               ...


>>>>                </jaxrs:server>






>>>> TO:


>>>>                <!-- CXF OpenAPIFeature -->


>>>>                <bean id="OidcSwaggerUiConfig"
>>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">


>>>>                               <property name="queryConfigEnabled"


>>>>                               <property name="url"
>>>> value="openapi.json"/>


>>>>                </bean>


>>>>                <bean id="OidcOpenApiFeature"
>>>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">


>>>>                               <property name="supportSwaggerUi"


>>>>                               <property name="swaggerUiConfig"
>>>> ref="OidcSwaggerUiConfig"/>


>>>>                               <property name="swaggerUiVersion"


>>>>                               <property name="scan" value="false"/>


>>>>                               <property name="useContextBasedConfig"


>>>>                               <property name="resourcePackages"
>>>> value="be.dvtm.aeo.op.oidc"/>


>>>>                </bean>


>>>>                <jaxrs:server id="OidcProviderApiServer"
>>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">


>>>>                               ....


>>>>                               <jaxrs:features>


>>>>                                              <ref
JPU>>> bean="OidcOpenApiFeature"


>>>>                               </jaxrs:features>


>>>>                               ...


>>>>                </jaxrs:server>










>>>> Now when starting my application and navigating to the root part "
>>>> http://localhost:localPort/op/services" I get an overview of all my
>>>> endpoints:






>>>> Now there are 3 RESTful service endpoints setup:


>>>>    1. ‘oidcsim’ which I switched to swagger v3 annotations
>>>>    2. ‘openapi’ currently still swagger v2 annotations
>>>>    3. ‘sdx’ currently still swagger v2 annotations






>>>> all endpoints work except for the ‘swagger endpoint address for the
>>>> oidcsim
>>>> endpoint:
>>>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services/o
>>>> i
>>>> dcsim/swagger.json


>>>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*
>>>> endpoint of the oidcsim resource. I am getting an error (the value of
>>>> the ‘url’ query parameter isn’t relevant):






>>>>         “WebApplicationException has been caught, status: 404,
>>>> message: HTTP 404 Not Found”






>>>> When I try (without the ‘/oidcsim’ context):
>>>> http://l-p53-008:8081/op/services/api-docs I get:


>>>>                “No service was found.”






>>>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs
>>>> doesn’t exist, where as the endpoint
>>>> http://l-p53-008:8081/op/services/api-docs does exist but no service
JPU>>> description is found?


>>>> Of course my intention is to get working, as previously with the
>>>> swagger v2 setup for which I then specifically added the
>>>> *Swagger2Feature* config
>>>> parameters:


>>>>                               <property name="basePath"
>>>> value="/op/services/oidcsim"/>


>>>>                               <property name="usePathBasedConfig"






>>>> But I don’t find the according configuration options for the
>>>> *OpenApiFeature* class or whether I should configure this in another
>>>> way.






>>>> Any suggestions on this?






>>>> Regards,






>>>> J.P.










>>>> -----Original Message-----
>>>> From: Andriy Redko <dr...@gmail.com>
>>>> Sent: donderdag 25 mei 2023 2:27
>>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>>>> dev@cxf.apache.org
>>>> Subject: Re: How to setup multiple JAXRS server endpoints






>>>> Hi Jean,






>>>> You may run into Swagger JAX-RS scanner limitations, as far as I can
>>>> tell - it checks class annotations for SwaggerDefinition, does not
>>>> traverse the hierarchy [1].






>>>> [1]
>>>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-
>>>> j
>>>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194






>>>> Best Regards,


>>>>     Andriy Redko






>>>>>  RE: How to setup multiple JAXRS server endpoints






>>>>> Still one question );






>>>>> The generated swagger file doesn’t take into account the


>>>>> @SwaggerDefintion on my interface classes?






>>>>> As a test I looked at


>>>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma


>>>>> in/release/samples/jax_rs/description_swagger2_web**


>>>>> and** modified** sample2*


>>>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma


>>>>> in/release/samples/jax_rs/description_swagger2_web


>>>>> and modified sample2> as follows:






>>>>>    @Path("/sample2")






>>>>>       @Api(value = "/sample2",authorizations=


>>>>>       {@Authorization(value="bearer")},description = "Sample2
>>>> (modified) JAX-RS


>>>>>       service with Swagger documentation")






>>>>>       @SwaggerDefinition(






>>>>>               info = @Info(






>>>>>                       description = "Sample2 server",






>>>>>                       version="1.0",






>>>>>                       title = "Test2",






>>>>>                       contact = @Contact(name = "J.P. Urkens",email = "


>>>>>       *jean-pierre.urkens@devoteam.com* <
>>>> jean-pierre.urkens@devoteam.com>


>>>>>       ")),






>>>>>               securityDefinition =


>>>>>       @SecurityDefinition(apiKeyAuthDefinitions=


>>>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="A
>>>> u
>>>> thorization",description="Use*


>>>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer


>>>>>       &lt;accessToken&gt;'")})






>>>>>       )






>>>>>       public class Sample2 {...}






>>>>> This correctly generates the ‘securityDefintions’ in the swagger file.






>>>>> If include the same @SwaggerDefinition and the authorizations on


>>>>> the @Api annotation as above in my interface classes then the


>>>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?






>>>>> Any idea what I might be missing?






>>>>> Regards,






>>>>> J.P.






>>>>> -----Original Message-----


>>>>> From: Jean Pierre URKENS <je...@devoteam.com>


>>>>> Sent: dinsdag 23 mei 2023 12:52


>>>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <




>>>>> Subject: RE: How to setup multiple JAXRS server endpoints






>>>>> Hi Andriy,






>>>>> I added the parameter usePathBasedConfig=true to the


>>>>> Swagger2Feature bean declarations but still it does generate an


>>>>> empty swagger.yaml for interfaces KmopResources and


>>>>> KmopDienstverlener although I noticed that for these interfaces the


>>>>> @Path() annotation was commented out (as I included it in the


>>>>> server declaration). After providing an empty @Path("") declaration
>>>>> on
>>>> the API interface classes everything worked.






>>>>> Thanks for the support.






>>>>> -----Original Message-----






>>>>> From: Andriy Redko <dr...@gmail.com>






>>>>> Sent: dinsdag 23 mei 2023 3:42






>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;


>>>>> dev@cxf.apache.org






>>>>> Subject: Re: How to setup multiple JAXRS server endpoints






>>>>> Hi Jean,






>>>>> The main problem to configure Swagger property in your particular


>>>>> case is that the server address is not "known" or "introspectable"
>>>>> for
>>>> Swagger.


>>>>> Intuitively, it has to be set manually using basePath to the,


>>>>> essentially, the server address






>>>>> part:






>>>>>  - /op/services/accounts






>>>>>  - /op/services/resources






>>>>>  - /op/services/dienstverlener






>>>>> You could read more about other Swagger properties you have asked here:


>>>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte


>>>>> gration-and-Configuration#configuration-properties






>>>>> You definitely need to set usePathBasedConfig to "true" otherwise


>>>>> you will see the same Swagger specs for all servers. We have a


>>>>> sample here which uses 2 jaxrs:server






>>>>> instances:


>>>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai


>>>>> n/release/samples/jax_rs/description_swagger2_web






>>>>> Regarding SwaggerUI, I think the value for each of those should be


>>>>> set to,


>>>>> respectively:






>>>>>  - /op/services/accounts/swagger.yaml






>>>>>  - /op/services/resources/swagger.yaml






>>>>>  - /op/services/dienstverlener/swagger.yaml






>>>>> I believe this is matching your settings already, except the


>>>>> usePathBasedConfig part. The example referred above could be


>>>>> helpful, my apologies if I missed something, there are quite a lot


>>>>> of questions :-) The fact that the generated Swagger specification


>>>>> is empty is unexpected - it should not happen when JAX-RS resources
>>>> are properly configured.






>>>>> Thank you.






>>>>> Best Regards,






>>>>>     Andriy Redko






>>>>>>  RE: How to setup multiple JAXRS server endpoints






>>>>>> Hi Andriy,






>>>>>> I am not quite understanding how to correctly configure the


>>>>> Swagger2Feature.






>>>>>> Referring to the attached cxf-endpoints configuration I (as a


>>>>>> test)






>>>>>> created






>>>>>> 3 JAXRS server instances:






>>>>>> 1.      A* KmopApiServer* server for the*






>>>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving






>>>>>> requests for URI path:






>>>>>>        * <protocol>**//<host:<port>/op/services/accounts*






>>>>>>    ‘op’  = root path of the web application






>>>>>>             ‘services’ = servlet path of the CXF-servlet






>>>>>>       The address of the server is set to ‘/accounts’ and the


>>>>>> @Path(…)






>>>>>>       annotation on the interface class was cleared.






>>>>>> 2.      A* Kmop**Resources**ApiServer* server for the*
>>>> be.dvtm.aeo.op.*






>>>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving






>>>>>> requests for URI path:






>>>>>>        * <protocol>**//<host:<port>/op/services/**resources*






>>>>>> The address of the server is set to ‘/resources’ and the @Path(…)






>>>>>> annotation on the interface class was cleared.






>>>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*


>>>>> be.dvtm.aeo.op.*






>>>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving






>>>>>> requests for URI path:






>>>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*






>>>>>> The address of the server is set to ‘/dienstverlener’ and the






>>>>>> @Path(…) annotation on the interface class was cleared.






>>>>>> For each of these server instances I’ve set the Swagger2Feature






>>>>>> with configuration as indicated in the attached cxf-endpoints.xml.






>>>>>> With regard to the configurations for the Swagger2Feature I’ve the






>>>>>> following questions:






>>>>>> a)      Referring to *
>>>> https://cxf.apache.org/docs/swagger2feature.html*






>>>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you






>>>>>> clarify on the following configuration parameters:






>>>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘






>>>>>> /op/services’) or to the JAX-RS server instance (e.g.






>>>>>> ‘/op/services/accounts’) or still something else? Is it used to






>>>>>> resolve service classes or is it just for documentation in the


>>>>>> swagger


>>>>> file?






>>>>>> *ii.    ** resourcePackage* – the description mentions ‘package names’






>>>>>> while the default mentions ‘service classes’? Service 2 and 3


>>>>>> above






>>>>>> are within the same package (generated from the same yaml






>>>>>> specification that included both interfaces).






>>>>>> *iii.   ** ig**noreRoutes* – is this taken into account when






>>>>>> scanAllResources=false?






>>>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter
>>>> value






>>>>>> (cf. question ‘a’)?






>>>>>> b)      What would be the correct URL to generate a swagger.yaml
>>>>>> file


>>>>> for






>>>>>> each of the above interfaces? Initially I called:






>>>>>> *i.     **


>>>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*






>>>>>> *ii.    **


>>>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*






>>>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*






>>>>>> *lener/swagger.yaml*






>>>>>>    All three requests delivered the same yaml specification,


>>>>>> namely


>>>>> the one






>>>>>>       for interface* KmopApiServer*?






>>>>>> c)      I tried to debug the processing of the requests under ‘b)’
>>>>>> and


>>>>> this






>>>>>> is done by the class JAXRSInterceptor#processRequest where the






>>>>>> MessageImpl object for request “ii.” looks like the one attached.






>>>>>> It finds 3 resource






>>>>>> classes:






>>>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl






>>>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource






>>>>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService






>>>>>> è       It matches the request to resource*


>>>>> Swagger2ApiListingResource* with






>>>>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*






>>>>>> process(…)* method.






>>>>>> è       Here it seems to go wrong. It generates a
>>>> SwaggerContextService






>>>>>> having basePath=/op/services/resources/,swaggerConfig=null,






>>>>>> usePathBasedConfig=null and then calls






>>>>>> SwaggerContextService.getSwagger()






>>>>>> which returns the Swagger definition for interface KmopApiServer?






>>>>>> It looks like it caches generated swagger definitions based on a






>>>>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the






>>>>>> same for all 3 interfaces as usePathBasedConfig=null






>>>>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is






>>>>>> derived from the ServletConfig parameter






>>>>>> ‘swagger.use.path.based.config’.* So should this be set on the






>>>>>> declaration of the CXFServlet** in web.xml?*






>>>>>> è       Actually the SwaggerConfig, the JaxrsScanner and the
>>>>>> generated


>>>>> Swagger






>>>>>> are cached using keys like






>>>>>> ‘swagger.config.id.[default|baseUriPath]’, ‘






>>>>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’


>>>>> is only done when usePathBasedconfig=true.






>>>>>> è       If I patch this to true then configIdKey=’






>>>>>> swagger.config.id./op/services/resources/’ and no swagger entry is






>>>>>> cached for this key so it will generate a new one. Again by






>>>>>> patching






>>>>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru


>>>>>> e






>>>>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”






>>>>>> è       Again Scanners are cached and if usePathBasedConfig=null it


>>>>> will use






>>>>>> the one cached under  ‘swagger.scanner.id.default’ and this again






>>>>>> returns the swagger definition for the KmopApiService interface.






>>>>>> è       So patching usePathBasedConfig=true will return a new one






>>>>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner






>>>>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘






>>>>>> which is correct. It will generate a new (but empty) Swagger object.






>>>>>> è       Next Swagger2ApiListingResource will call the






>>>>>> customizer.customize(s), which still isn’t putting anything new in






>>>>>> the Swagger object. Should it or should the next step do this?






>>>>>> è       Next BaseApiListingResource#getListing(…) is called which on


>>>>> its






>>>>>> turn calls getListingYamlResponse(..)






>>>>>> è       The final result is a swagger.yaml document with following


>>>>> content:






>>>>>>    swagger: "2.0"






>>>>>>       info:






>>>>>>         license:






>>>>>>           name: "Apache 2.0 License"






>>>>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html






>>>>>>       basePath: "/op/services/resources"






>>>>>>        So basically an empty swagger file.






>>>>>> d)      The usePathBasedConfig is derived from the ServletConfig


>>>>> parameter ‘






>>>>>> swagger.use.path.based.config’. Without this parameter set to true






>>>>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger






>>>>>> object.* So should this be set on the declaration of the






>>>>>> CXFServlet** in web.xml?*






>>>>>> The majority in this processing happens in the library






>>>>>> swagger-jaxrs-v1.6.10 which is included as a dependency on


>>>>> cxf-rt-rs-service-description-swagger.






>>>>>> Even if I patch usePathBasedConfig=true about everywhere where I






>>>>>> met this it still doesn’t generate a correct swagger.yaml. Am I






>>>>>> still missing some configuration parameter?






>>>>>> Any suggestions on how to resolve this would be welcome.






>>>>>> Regards,






>>>>>> J.P. Urkens










































>>>>>> <<...>> <<...>>






>>>>>> -----Original Message-----






>>>>>> From: Andriy Redko <dr...@gmail.com>






>>>>>> Sent: maandag 8 mei 2023 23:15






>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev






>>>>>> List <












>>>>>> Subject: Re: How to setup multiple JAXRS server endpoints






>>>>>> Hi Jean,






>>>>>> Indeed the way you would like to do that is somewhat tricky.






>>>>>>> So I tried to keep the @Path declaration on the interface classes


>>>>>>> but






>>>>>> changed them to @Path(“”). That does seems to work except the






>>>>>> swagger stuff no longer correctly works.






>>>>>> This is one of the possible options but OpenAPI/Swagger gets






>>>>>> confused for a






>>>>>> reason: the path is now implicit (not in the spec).






>>>>>> So how about this option:






>>>>>>  - use only one JAX-RS server (address "/")






>>>>>>  - host both resources but use @Path("accounts") and






>>>>>> @Path("resources") on them respectively










>>>>>> I see that for @Path("accounts") you need to apply the






>>>>>> "kmopApiAuthorizationFilter", that could be done using






>>>>>> DynamicFeature [1], [2]. If this is not the option and you would






>>>>>> prefer to use 2 separate JAX-RS servers, you may need to provide






>>>>>> your own instance of Swagger2Customizer [3], [4] which allows to






>>>>>> transform the OpenAPI/Swagger on the fly. Please let me know if


>>>>>> that


>>>>> would it work for you, thank you.






>>>>>> [1]






>>>>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic


>>>>>> F






>>>>>> eature.html






>>>>>> [2]






>>>>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born


>>>>>> -






>>>>>> equal.html






>>>>>> [3]






>>>>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger


>>>>>> /






>>>>>> Swagger2Customizer.html






>>>>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has






>>>>>> customizer






>>>>>> property)










>>>>>> Best Regards,






>>>>>>     Andriy Redko






>>>>>>> Hi Andriy,






>>>>>>> I am again getting into trouble with server endpoint declarations.






>>>>>>> Now






>>>>>> because I am adding additional JAX-RS endpoints.






>>>>>>> The issue is with:






>>>>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration
>>>>>>> in






>>>>>> combination with






>>>>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the
>>>>>>> web.xml






>>>>>> in combination with






>>>>>>> 3.      The @Path declaration in the interface class in combination
>>>>>>> with






>>>>>>> 4.      The @Path declaration on the interface method in
>>>>>>> combination
>>>> with






>>>>>>> So what I had is that my web application deployed under baseUlr 'op'






>>>>>>> had






>>>>>> one JAXRS server endpoint with declarations like:






>>>>>>> 1.      <jaxrs:server id="restServer"






>>>>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">






>>>>>>> 2.      <url-pattern>/services/*</url-pattern>






>>>>>>> 3.      @Path("accounts") on the public interface class






>>>>>>> 4.      @Path("/{authorisationId}/customerFund") on the
>>>>>>> customerFund






>>>>>> interface method






>>>>>>> A valid API call would thus be e.g.:






>>>>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/c
>>>>>>> u
>>>>>>> s


>>>>>>> t






>>>>>>> o






>>>>>>> merFund






>>>>>>> And this works correctly.






>>>>>>> We're now introducing additional JAX-RS service endpoints and now
>>>>>>> I






>>>>>>> am






>>>>>> running into problems. This second endpoint was declared with:






>>>>>>> 1.      <jaxrs:server id="resourceServer"






>>>>>> basePackages="be.dvtm.aeo.op.resources" address="/">






>>>>>>> 2.      <url-pattern>/services/*</url-pattern>






>>>>>>> 3.      @Path("resources") on the public interface class






>>>>>>> 4.      @Path("/NACE") on the NACE interface method






>>>>>>> So here a valid API call woud be:






>>>>>> https://<hostname>:<port>/op/services/resources/NACE.






>>>>>>> The problem is that I can not declare two <jaxrs:server> entries


>>>>>>> with






>>>>>>> the






>>>>>> same ‘address’ as it throws the exception:






>>>>>>> Caused by:
>>>>>>> org.apache.cxf.service.factory.ServiceConstructionException:






>>>>>> There is an endpoint already running on /.






>>>>>>>  So I tried changing the addresses to:






>>>>>>> ·       address=”accounts” for the restServer






>>>>>>> ·       address=”resources” for the resourceServer






>>>>>>> But to keep the API-call URLs the same I removed the @Path






>>>>>>> declaration on






>>>>>> the interface classes. By doing so the <jaxrs:server> bean






>>>>>> declarations no longer loads successfully.






>>>>>>> So I tried to keep the @Path declaration on the interface classes


>>>>>>> but






>>>>>> changed them to @Path(“”). That does seems to work except the






>>>>>> swagger stuff no longer correctly works.






>>>>>>> So what is the decent way to setup multiple JAX-RS server
>>>>>>> endpoints






>>>>>>> where






>>>>>> each server has its own configuration regarding supported features:






>>>>>>> ·       own validation






>>>>>>> ·       own object and exception mappings






>>>>>>> ·       own swagger file generation






>>>>>>> ·       own logging (in separate file if possible)






>>>>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in






>>>>>>> cooperation






>>>>>> with swager-ui v4.5.0.






>>>>>>> Below the declarations of my endpoints <<...>> Thanks for any advice.






>>>>>>> Regards,






>>>>>>> J.P. Urkens






>>>>>>> -----Original Message-----






>>>>>>> From: Andriy Redko <dr...@gmail.com>






>>>>>>> Sent: zaterdag 18 juni 2022 1:12






>>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;






>>>>>>> issues@cxf.apache.org; dev@cxf.apache.org






>>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi
>>>>>>> Jean,






>>>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'






>>>>>>> Correct, so in the relative form like address="/<something>", the






>>>>>>> JAX-RS






>>>>>> endpoint path would be:






>>>>>>>     <baseUrl>/<servlet path






mapping>>>>>>>>/<address>/[@ApplicationPath]/[@Path]






>>>>>>> The @ApplicationPath is optional in this case.






>>>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'






>>>>>>> The JAX-WS is very different from JAX-RS, essentially the action






>>>>>>> comes






>>>>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/






>>>>>> (@Path / @ApplicationPath are not relevant there).






>>>>>>>> Question: Because now address="/" is set for the jaxrs:server
>>>>>>>> will






>>>>>>>> it






>>>>>>>> also inspect requests targeted for the jaxws service as those






>>>>>>>> requests have start with the same path '/<basePath>/services/...






>>>>>>> This is a good question, I have not done it myself but I think it






>>>>>>> should






>>>>>> work:






>>>>>>> the servlet dispatches according to registered services, in this






>>>>>>> regard






>>>>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?


>>>>> Thank you.






>>>>>>> Best Regards,






>>>>>>>     Andriy Redko






>>>>>>>> Hi Andriy,






>>>>>>>> Using address="/" seems to work but still I don't understand how


>>>>>>>> the






>>>>>>>> following work together:






>>>>>>>>  - path specification in servlet mapping for the CXF servlet






>>>>>>>> (org.apache.cxf.transport.servlet.CXFServlet)






>>>>>>>>  - the 'address' attribute on the jaxrs:server bean declaration






>>>>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the






>>>>>>>> service API description Say I've two services with (relateive to


>>>>>>>> the






>>>>>>>> host) url's:






>>>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'






>>>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'






>>>>>>>> How do I configure above 3 aspects? Currently I have (working):






>>>>>>>> 1.for the jaxrs:server endpoint:






>>>>>>>>         - servlet path mapping: '/services/*'






>>>>>>>>                - jaxrs-server address attribute: address="/"






>>>>>>>>                - @Path annotation: @Path("service1") 2.For the


>>>>>>>> jaxws






>>>>>>>> service endpoint:






>>>>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS






>>>>>>>> requests are handleb by the same CXF servle)






>>>>>>>>                - jaxws:endpoint server address attribute:






>>>>>>>> address="/service2"






>>>>>>>>                - @WebService(name="service2") A correct request
>>>>>>>> for






>>>>>>>> '1' would be '/basePath>/services/service1/<ID>'.






>>>>>>>> A correct request for '2' would be '/basePath>/services/service2'.






>>>>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect
>>>>>>>> to:






>>>>>>>>         - the server address attribute






>>>>>>>>         - The API annotation (@Path or @Webservice) The JAXWS


>>>>>>>> server






>>>>>>>> address attribute doesn't seem to interfere with the @Webservice






>>>>>>>> annotation. While the jaxrs server address attribute does seem to






>>>>>>>> interfere with the @Path annotation. I would have expected the


>>>>>>>> jaxrs






>>>>>>>> server aspects to be configured as:






>>>>>>>>         - servlet path mapping: '/services/*'






>>>>>>>>                - jaxrs-server address attribute: address="/service1"






>>>>>>>>                - @Path annotation: @Path("service1") but then a






>>>>>>>> valid






>>>>>>>> request would be






>>>>>>>>> /services/service1/service1/<ID>'.






>>>>>>>> For both the 'address' attribute is relative to the servlet path.






>>>>>>>> The @Path Javadoc mentions that this path is relative to the






>>>>>>>> ApplicationPath which thus seems to be relative to the
>>>>>>>> jaxrs-server






>>>>>>>> address attribute. As for @Webservice it doesnn't seem to be






>>>>>>>> url-path






>>>>>> related.






>>>>>>>> Question: Because now address="/" is set for the jaxrs:server
>>>>>>>> will






>>>>>>>> it






>>>>>>>> also inspect requests targeted for the jaxws service as those






>>>>>>>> requests have start with the same path '/<basePath>/services/...'.






>>>>>>>> Albeit somewhat confusing.






>>>>>>>> J.P.






>>>>>>>> -----Original Message-----






>>>>>>>> From: Andriy Redko <dr...@gmail.com>






>>>>>>>> Sent: dinsdag 14 juni 2022 1:08






>>>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;






>>>>>>>> issues@cxf.apache.org; dev@cxf.apache.org






>>>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi
>>>>>>>> Jean,






>>>>>>>> Indeed, the jaxrs:server does not expect address to be omitted,
>>>>>>>> you






>>>>>>>> could use the "/" (and I believe an empty string would also make
>>>>>>>> it):






>>>>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...






>>>>>>>> </jaxrs:server>






>>>>>>>> Thank you.






>>>>>>>> Hope it helps.






>>>>>>>> Best Regards,






>>>>>>>>     Andriy Redko






>>>>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean






>>>>>>>>> declarations






>>>>>>>>> like:






>>>>>>>>>      <jaxrs:server id="restServer" basePackages="xxx">






>>>>>>>>>            <jaxrs:serviceBeans>






>>>>>>>>>                 <ref bean="TestApi" />






>>>>>>>>>            </jaxrs:serviceBeans>






>>>>>>>>>            <jaxrs:providers>






>>>>>>>>>                 <…/>






>>>>>>>>>            </jaxrs:providers>






>>>>>>>>>            <jaxrs:features>






>>>>>>>>>                 <… />






>>>>>>>>>            </jaxrs:features>






>>>>>>>>>            <jaxrs:inInterceptors>






>>>>>>>>>                 <… />






>>>>>>>>>            </jaxrs:inInterceptors>






>>>>>>>>>            <jaxrs:outInterceptors>*






>>>>>>>>>                 <**…**/>*






>>>>>>>>>            </jaxrs:outInterceptors>*






>>>>>>>>>      </jaxrs:server>










>>>>>>>>> Here my “TestApi” bean interface is declared like:






>>>>>>>>>       @Path("accounts")






>>>>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)






>>>>>>>>>        @Produces(MediaType.*APPLICATION_JSON*)






>>>>>>>>>        public interface TestApi {






>>>>>>>>>          …






>>>>>>>>>        }






>>>>>>>>> And CXF is triggered via a servlet configuration like:






>>>>>>>>>      <servlet>






>>>>>>>>>              <display-name>CXF Servlet</display-name>






>>>>>>>>>              <servlet-name>CXFServlet</servlet-name>






>>>>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</serv
>>>>>>>>> l
>>>>>>>>> e






>>>>>>>>> t












>>>>>>>>>        </servlet>






>>>>>>>>>        <servlet-mapping>






>>>>>>>>>              <servlet-name>CXFServlet</servlet-name>






>>>>>>>>>              <url-pattern>/services/*</url-pattern>






>>>>>>>>>        </servlet-mapping>










>>>>>>>>> Because I’ve got the @Path declaration on the interface type
>>>>>>>>> I’ve






>>>>>>>>> omitted






>>>>>>>>> the address=”accounts” attribute on the jaxrs:server declaration






>>>>>>>>> since otherwise






>>>>>>>>> I noticed that the server would be listening to






>>>>>>>>> /basepath/services/ accounts/accounts/…).






>>>>>>>>> Now this configuration works perfectly, only when shutting down






>>>>>>>>> the application server cxf calls






>>>>>>>>>         ServerImpl#destroy()






>>>>>>>>> which delegates (via Obeservable) to






>>>>>>>>> AbstractHTTPDestination#deactivate()






>>>>>>>>> which calls






>>>>>>>>> registry.removeDestination(path).






>>>>>>>>> This path is null (no ‘address’ specified on jaxrs:server






>>>>>>>>> declaration) and results in a NPE on the registry Map.






>>>>>>>>> This causes an unclean shutdown of my server.






>>>>>>>>> Is this an error in cxf or is my jaxrs:server configured
>>>>>>>>> incorrectly?






>>>>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration






>>>>>>>>> correctly interact with the @Path parameter on the API interface?






>>>>>> <<...>>


RE: How to setup multiple JAXRS server endpoints

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
The @Parameter annotation seems to be ignored at this level.

-----Original Message-----
From: Jean Pierre URKENS <je...@devoteam.com>
Sent: donderdag 13 juli 2023 7:11
To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'
<de...@cxf.apache.org>
Subject: RE: How to setup multiple JAXRS server endpoints

Yes, SwaggerUI works too!
I noticed that v2.x of swagger-jaxrs relates to OpenApi v3.1.x while my spec
is compliant with OpenApi v3.0.x, so I am going to stick with v2.1.13 which
seems to be that last version for OpenApi v3.0.x.

I thought the @Parameter only applied to input parameters ("query",
"header", "path" or "cookie" parameters), but I'll give it a try.

J.P.

-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: woensdag 12 juli 2023 22:16
To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
Subject: Re: How to setup multiple JAXRS server endpoints

Hi Jean,

That's awesome, have you got SwaggerUI working as well?

Yes, you could use 2.2.15 (we already updated to this version, no
regressions). It seems like the description applies to the whole schema
(which is the same for both properties), may be you could use @Parameter
instead:

@Parameter(description="The description I want for prop1")

Thank you.

Best Regards,
    Andriy Redko

> Hi Andriy,
> After having migrated everything to "io.swagger.v3.oas.annotations.*" the
> swagger endpoints for each of my services became active.
> So far so good, but I do notice that there are discrepancies when
> annotating models, e.g.:
>  public class Model1 {
>   @Schema(description="The description I want for prop1")
>    private Model2 prop1;
>   @Schema(description="The description I want for prop2")
>    private Model2 prop2;
>   ...
> }
> When I generate the openapi.[json|yaml] specification I see that both
> prop1 and prop2 have a reference to the schema component "Model2" with
> description ' The description I want for prop2' which is inappropriate for
> 'prop1'.
> It is not unlikely to have multiple properties within one Model that are
> of the same class but are semantically used in a different context. E.g.
> something as simple as a ShipmentOrder having two 'Address' properties
> 'from' and 'to' would result in wrong API documentation.
> I am aware it has nothing to do with CXF but rather with
> swagger-jaxrs2-vx.y.z.jar and depending libraries. CXF-3.5.6 has
> dependency on swagger-jaxrs2-2.1.13.jar. Would it be an issue to replace
> this dependency with e.g. swagger-jaxrs2-2.2.15.jar (latest stable release
> according to maven central repo)?
> J.P.
> -----Original Message-----
> From: Jean Pierre URKENS <je...@devoteam.com>
> Sent: woensdag 12 juli 2023 8:25
> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'
> <de...@cxf.apache.org>
> Subject: RE: How to setup multiple JAXRS server endpoints I seem to be
> mistaken here, the endpoint was loaded (I did a manual HTTP GET test to
> the endpoint to verify this) although no breakpoints where hit during
> startup.
> I am first going to complete the migration to
> "io.swagger.v3.oas.annotations.*" annotations for all endpoints and then I
> am going to test again.
> The application is composed of libraries, some of which use SLF4J but most
> use LOG4J for logging.
> J.P.

> -----Original Message-----
> From: Andriy Redko <dr...@gmail.com>
> Sent: woensdag 12 juli 2023 1:13
> To: Jean Pierre URKENS <je...@devoteam.com>;
> dev@cxf.apache.org
> Subject: Re: How to setup multiple JAXRS server endpoints Hi Jean, The
> OpenApiFeature$Portable#initiliaze(…) should definitely be called
> (otherwise you shouldn't even see the openapi.json endpoint), so I am not
> sure why these are not triggering for you.
>
> For logging, it seems like you are using SLF4J
> (org.apache.cxf.common.logging.Slf4jLogger),
> and also reload4j (aka log4j), why do you need both?
> Thank you.
> Best Regards,
>     Andriy Redko
JPU>> After some code investigation:


JPU>> OpenApiFeature implements SwaggerUiSupport and in its
JPU>> portable#registerSwaggerUiResources(…) method it will call
JPU>> SwaggerUiSupport#getSwaggerUi(…) which will register the
SwaggerUiService.


JPU>> I have put breakpoints on:
JPU>>    - OpenApiFeature$Portable#initiliaze(…)
JPU>>    - SwaggerUiService constructor
JPU>>    - SwaggerUiSupport#getSwaggerUi(…)


JPU>> but none of them are hit when starting my application?


JPU>> Although the (spring) logging shows all beans in my
JPU>> cxf-endpoints.xml have been created?
JPU>> The *WADL* and *OpenAPI* endpoints to get the specification work.
JPU>> Even the actual endpoint seems to work although I didn’t hit any
JPU>> of the breakpoint?


JPU>> CXF, also doesn’t seem to log a lot, I am hardly getting any log
JPU>> entries although log level I set to DEBUG.
JPU>> My logging (except wire message logging) for cxf is setup
JPU>> correctly (I
JPU>> think):
JPU>>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line
JPU>>    ‘org.apache.cxf.common.logging.Slf4jLogger’
JPU>>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and
JPU>>    reload4j-1.2.19.jar are on the classpath
JPU>>    - the log4j.properties file contains the line:
JPU>>    ‘log4j.logger.org.apache.cxf=DEBUG’


JPU>> There are no special instructions mentioned on
JPU>> https://cxf.apache.org/docs/general-cxf-logging.html so the above
JPU>> should work (it works for all other packages I use in my application).


JPU>> J.P.
JPU>> *From:* Jean Pierre URKENS <je...@devoteam.com>
JPU>> *Sent:* dinsdag 11 juli 2023 9:58
JPU>> *To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <
dev@cxf.apache.org>>>
JPU>> *Subject:* RE: How to setup multiple JAXRS server endpoints


JPU>> Hi Andriy,


JPU>> As a test I removed all JAX-RS endpoints that use Swagger v2
JPU>> annotations from my configuration file (see attachment).
JPU>> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger v3
JPU>> annotations, using the OpenApiFeature i.o. Swagger2Feature.
JPU>> If I run my server with this configuration I only get the (working)
JPU>> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint:




JPU>> So there is some configuration missing to detect/activate the
JPU>> Swagger endpoint. When I look at the samples that come with the
JPU>> distribution of CXF (I am using v3.5.6) nothing special seems to be
configured to activate this?
JPU>> Do you have any idea how the SwaggerUiService is picked up when
loading?


JPU>> J.P.


JPU>> -----Original Message-----
JPU>> From: Andriy Redko <dr...@gmail.com>
JPU>> Sent: dinsdag 11 juli 2023 3:44
JPU>> To: Jean Pierre URKENS <je...@devoteam.com>;
JPU>> dev@cxf.apache.org
JPU>> Subject: Re: How to setup multiple JAXRS server endpoints


JPU>> Hi Jean,


JPU>> I guess you figured one issue, swagger.json -> openapi.json, but to
JPU>> be honest we have never tested or envisioned the application that
JPU>> would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same time, I
JPU>> am afraid this is just not supported. You may get things back on
JPU>> track when going with OpenAPI 3.0 for all services.


JPU>> Thank you.


JPU>> Best Regards,
JPU>>     Andriy Redko




>>> Hi Andriy,






>>> I am trying to trace the difference in handling with another
>>> application where I’ve got only one CXF service endpoint that uses
>>> swagger v3 openapi annotations.


>>> There I see that when handling the Swagger page request (
>>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json) the
>>> JAXRSInInterceptor is calling:






>>> *JAXRSUtils.**getRootResources*(Message message)






>>> It contains 4 entries:


>>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint
>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource
>>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService














>>> On the application described below with the service ‘oidcsim’ when
>>> calling the swagger page request
>>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the
>>> result of the getRootResources doesn’t contain the ClassResourceInfo
>>> ‘
>>> SwaggerUiService’. It only contains 3 entries:


>>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)
>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource






>>> The SwaggerUiService is the one that is configured to handle the
JPU>> ‘api-docs’
>>> path-request. Since it is missing the request is tried to match with
>>> the other two resources but fails, hence ‘NOT FOUND’ exception.






>>> I can’t trace back where these rootResources are set and why the
>>> SwaggerUiService’ isn’t listed.






>>> J.P.


>>> *From:* Jean Pierre URKENS <je...@devoteam.com>
>>> *Sent:* maandag 10 juli 2023 13:43
>>> *To:* 'Andriy Redko' <dr...@gmail.com>
>>> *Subject:* RE: How to setup multiple JAXRS server endpoints






>>> Andriy,






>>> I am trying to switch from Swagger v2 to OpenApi v3 annotations
>>> basically because my starting point is an OpenApi v3.0.7 yaml file
>>> description and OpenAPI seems to be the way forward.


>>> For applications where I have only one CXF JAX-RS endpoint exposed I
>>> had no problems converting. However as soon as there are multiple
>>> endpoints I run into troubles.






>>> So, to recall, I've an application exposing 3 JAX-RS endpoints that
>>> where previously annotated with swagger v2 annotations (i.e. package
>>> io.swagger.annotations.*) which I migrated to


>>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*). In
>>> accordance I altered my CXF JAX-RS endpoint configuration from (only
>>> showing relevant parts, see attachment for full setup):






>>>                <!-- CXF Swagger2Feature -->


>>>                <bean id="SwaggerUiConfigOidcApi"
>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">


>>>                               <property name="queryConfigEnabled"


>>>                               <property name="url"
>>> value="/op/services/oidcsim/swagger.yaml"/>


>>>                </bean>


>>>                <bean id="Swagger2FeatureOidcApi"
>>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">


>>>                               <property name="basePath"
>>> value="/op/services/oidcsim"/>


>>>                               <property name="usePathBasedConfig"


>>>                               <property name="resourcePackage"
>>> value="be.dvtm.aeo.op.oidc"/>


>>>                               <property name="supportSwaggerUi"


>>>                               <property name="swaggerUiConfig"
>>> ref="SwaggerUiConfigOidcApi"/>


>>>                </bean>


>>>                <jaxrs:server id="OidcProviderApiServer"
>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">


>>>                               ....


>>>                               <jaxrs:features>


>>>                                              <ref
>>> bean="Swagger2FeatureOidcApi" />


>>>                               </jaxrs:features>


>>>                               ...


>>>                </jaxrs:server>






>>> TO:


>>>                <!-- CXF OpenAPIFeature -->


>>>                <bean id="OidcSwaggerUiConfig"
>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">


>>>                               <property name="queryConfigEnabled"


>>>                               <property name="url"
>>> value="openapi.json"/>


>>>                </bean>


>>>                <bean id="OidcOpenApiFeature"
>>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">


>>>                               <property name="supportSwaggerUi"


>>>                               <property name="swaggerUiConfig"
>>> ref="OidcSwaggerUiConfig"/>


>>>                               <property name="swaggerUiVersion"


>>>                               <property name="scan" value="false"/>


>>>                               <property name="useContextBasedConfig"


>>>                               <property name="resourcePackages"
>>> value="be.dvtm.aeo.op.oidc"/>


>>>                </bean>


>>>                <jaxrs:server id="OidcProviderApiServer"
>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">


>>>                               ....


>>>                               <jaxrs:features>


>>>                                              <ref
JPU>> bean="OidcOpenApiFeature"


>>>                               </jaxrs:features>


>>>                               ...


>>>                </jaxrs:server>










>>> Now when starting my application and navigating to the root part "
>>> http://localhost:localPort/op/services" I get an overview of all my
>>> endpoints:






>>> Now there are 3 RESTful service endpoints setup:


>>>    1. ‘oidcsim’ which I switched to swagger v3 annotations
>>>    2. ‘openapi’ currently still swagger v2 annotations
>>>    3. ‘sdx’ currently still swagger v2 annotations






>>> all endpoints work except for the ‘swagger endpoint address for the
>>> oidcsim
>>> endpoint:
>>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services/o
>>> i
>>> dcsim/swagger.json


>>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*
>>> endpoint of the oidcsim resource. I am getting an error (the value of
>>> the ‘url’ query parameter isn’t relevant):






>>>         “WebApplicationException has been caught, status: 404,
>>> message: HTTP 404 Not Found”






>>> When I try (without the ‘/oidcsim’ context):
>>> http://l-p53-008:8081/op/services/api-docs I get:


>>>                “No service was found.”






>>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs
>>> doesn’t exist, where as the endpoint
>>> http://l-p53-008:8081/op/services/api-docs does exist but no service
JPU>> description is found?


>>> Of course my intention is to get working, as previously with the
>>> swagger v2 setup for which I then specifically added the
>>> *Swagger2Feature* config
>>> parameters:


>>>                               <property name="basePath"
>>> value="/op/services/oidcsim"/>


>>>                               <property name="usePathBasedConfig"






>>> But I don’t find the according configuration options for the
>>> *OpenApiFeature* class or whether I should configure this in another
>>> way.






>>> Any suggestions on this?






>>> Regards,






>>> J.P.










>>> -----Original Message-----
>>> From: Andriy Redko <dr...@gmail.com>
>>> Sent: donderdag 25 mei 2023 2:27
>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>>> dev@cxf.apache.org
>>> Subject: Re: How to setup multiple JAXRS server endpoints






>>> Hi Jean,






>>> You may run into Swagger JAX-RS scanner limitations, as far as I can
>>> tell - it checks class annotations for SwaggerDefinition, does not
>>> traverse the hierarchy [1].






>>> [1]
>>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-
>>> j
>>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194






>>> Best Regards,


>>>     Andriy Redko






>>>>  RE: How to setup multiple JAXRS server endpoints






>>>> Still one question );






>>>> The generated swagger file doesn’t take into account the


>>>> @SwaggerDefintion on my interface classes?






>>>> As a test I looked at


>>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma


>>>> in/release/samples/jax_rs/description_swagger2_web**


>>>> and** modified** sample2*


>>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma


>>>> in/release/samples/jax_rs/description_swagger2_web


>>>> and modified sample2> as follows:






>>>>    @Path("/sample2")






>>>>       @Api(value = "/sample2",authorizations=


>>>>       {@Authorization(value="bearer")},description = "Sample2
>>> (modified) JAX-RS


>>>>       service with Swagger documentation")






>>>>       @SwaggerDefinition(






>>>>               info = @Info(






>>>>                       description = "Sample2 server",






>>>>                       version="1.0",






>>>>                       title = "Test2",






>>>>                       contact = @Contact(name = "J.P. Urkens",email = "


>>>>       *jean-pierre.urkens@devoteam.com* <
>>> jean-pierre.urkens@devoteam.com>


>>>>       ")),






>>>>               securityDefinition =


>>>>       @SecurityDefinition(apiKeyAuthDefinitions=


>>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="A
>>> u
>>> thorization",description="Use*


>>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer


>>>>       &lt;accessToken&gt;'")})






>>>>       )






>>>>       public class Sample2 {...}






>>>> This correctly generates the ‘securityDefintions’ in the swagger file.






>>>> If include the same @SwaggerDefinition and the authorizations on


>>>> the @Api annotation as above in my interface classes then the


>>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?






>>>> Any idea what I might be missing?






>>>> Regards,






>>>> J.P.






>>>> -----Original Message-----


>>>> From: Jean Pierre URKENS <je...@devoteam.com>


>>>> Sent: dinsdag 23 mei 2023 12:52


>>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <




>>>> Subject: RE: How to setup multiple JAXRS server endpoints






>>>> Hi Andriy,






>>>> I added the parameter usePathBasedConfig=true to the


>>>> Swagger2Feature bean declarations but still it does generate an


>>>> empty swagger.yaml for interfaces KmopResources and


>>>> KmopDienstverlener although I noticed that for these interfaces the


>>>> @Path() annotation was commented out (as I included it in the


>>>> server declaration). After providing an empty @Path("") declaration
>>>> on
>>> the API interface classes everything worked.






>>>> Thanks for the support.






>>>> -----Original Message-----






>>>> From: Andriy Redko <dr...@gmail.com>






>>>> Sent: dinsdag 23 mei 2023 3:42






>>>> To: Jean Pierre URKENS <je...@devoteam.com>;


>>>> dev@cxf.apache.org






>>>> Subject: Re: How to setup multiple JAXRS server endpoints






>>>> Hi Jean,






>>>> The main problem to configure Swagger property in your particular


>>>> case is that the server address is not "known" or "introspectable"
>>>> for
>>> Swagger.


>>>> Intuitively, it has to be set manually using basePath to the,


>>>> essentially, the server address






>>>> part:






>>>>  - /op/services/accounts






>>>>  - /op/services/resources






>>>>  - /op/services/dienstverlener






>>>> You could read more about other Swagger properties you have asked here:


>>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte


>>>> gration-and-Configuration#configuration-properties






>>>> You definitely need to set usePathBasedConfig to "true" otherwise


>>>> you will see the same Swagger specs for all servers. We have a


>>>> sample here which uses 2 jaxrs:server






>>>> instances:


>>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai


>>>> n/release/samples/jax_rs/description_swagger2_web






>>>> Regarding SwaggerUI, I think the value for each of those should be


>>>> set to,


>>>> respectively:






>>>>  - /op/services/accounts/swagger.yaml






>>>>  - /op/services/resources/swagger.yaml






>>>>  - /op/services/dienstverlener/swagger.yaml






>>>> I believe this is matching your settings already, except the


>>>> usePathBasedConfig part. The example referred above could be


>>>> helpful, my apologies if I missed something, there are quite a lot


>>>> of questions :-) The fact that the generated Swagger specification


>>>> is empty is unexpected - it should not happen when JAX-RS resources
>>> are properly configured.






>>>> Thank you.






>>>> Best Regards,






>>>>     Andriy Redko






>>>>>  RE: How to setup multiple JAXRS server endpoints






>>>>> Hi Andriy,






>>>>> I am not quite understanding how to correctly configure the


>>>> Swagger2Feature.






>>>>> Referring to the attached cxf-endpoints configuration I (as a


>>>>> test)






>>>>> created






>>>>> 3 JAXRS server instances:






>>>>> 1.      A* KmopApiServer* server for the*






>>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving






>>>>> requests for URI path:






>>>>>        * <protocol>**//<host:<port>/op/services/accounts*






>>>>>    ‘op’  = root path of the web application






>>>>>             ‘services’ = servlet path of the CXF-servlet






>>>>>       The address of the server is set to ‘/accounts’ and the


>>>>> @Path(…)






>>>>>       annotation on the interface class was cleared.






>>>>> 2.      A* Kmop**Resources**ApiServer* server for the*
>>> be.dvtm.aeo.op.*






>>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving






>>>>> requests for URI path:






>>>>>        * <protocol>**//<host:<port>/op/services/**resources*






>>>>> The address of the server is set to ‘/resources’ and the @Path(…)






>>>>> annotation on the interface class was cleared.






>>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*


>>>> be.dvtm.aeo.op.*






>>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving






>>>>> requests for URI path:






>>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*






>>>>> The address of the server is set to ‘/dienstverlener’ and the






>>>>> @Path(…) annotation on the interface class was cleared.






>>>>> For each of these server instances I’ve set the Swagger2Feature






>>>>> with configuration as indicated in the attached cxf-endpoints.xml.






>>>>> With regard to the configurations for the Swagger2Feature I’ve the






>>>>> following questions:






>>>>> a)      Referring to *
>>> https://cxf.apache.org/docs/swagger2feature.html*






>>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you






>>>>> clarify on the following configuration parameters:






>>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘






>>>>> /op/services’) or to the JAX-RS server instance (e.g.






>>>>> ‘/op/services/accounts’) or still something else? Is it used to






>>>>> resolve service classes or is it just for documentation in the


>>>>> swagger


>>>> file?






>>>>> *ii.    ** resourcePackage* – the description mentions ‘package names’






>>>>> while the default mentions ‘service classes’? Service 2 and 3


>>>>> above






>>>>> are within the same package (generated from the same yaml






>>>>> specification that included both interfaces).






>>>>> *iii.   ** ig**noreRoutes* – is this taken into account when






>>>>> scanAllResources=false?






>>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter
>>> value






>>>>> (cf. question ‘a’)?






>>>>> b)      What would be the correct URL to generate a swagger.yaml
>>>>> file


>>>> for






>>>>> each of the above interfaces? Initially I called:






>>>>> *i.     **


>>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*






>>>>> *ii.    **


>>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*






>>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*






>>>>> *lener/swagger.yaml*






>>>>>    All three requests delivered the same yaml specification,


>>>>> namely


>>>> the one






>>>>>       for interface* KmopApiServer*?






>>>>> c)      I tried to debug the processing of the requests under ‘b)’
>>>>> and


>>>> this






>>>>> is done by the class JAXRSInterceptor#processRequest where the






>>>>> MessageImpl object for request “ii.” looks like the one attached.






>>>>> It finds 3 resource






>>>>> classes:






>>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl






>>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource






>>>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService






>>>>> è       It matches the request to resource*


>>>> Swagger2ApiListingResource* with






>>>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*






>>>>> process(…)* method.






>>>>> è       Here it seems to go wrong. It generates a
>>> SwaggerContextService






>>>>> having basePath=/op/services/resources/,swaggerConfig=null,






>>>>> usePathBasedConfig=null and then calls






>>>>> SwaggerContextService.getSwagger()






>>>>> which returns the Swagger definition for interface KmopApiServer?






>>>>> It looks like it caches generated swagger definitions based on a






>>>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the






>>>>> same for all 3 interfaces as usePathBasedConfig=null






>>>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is






>>>>> derived from the ServletConfig parameter






>>>>> ‘swagger.use.path.based.config’.* So should this be set on the






>>>>> declaration of the CXFServlet** in web.xml?*






>>>>> è       Actually the SwaggerConfig, the JaxrsScanner and the
>>>>> generated


>>>> Swagger






>>>>> are cached using keys like






>>>>> ‘swagger.config.id.[default|baseUriPath]’, ‘






>>>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’


>>>> is only done when usePathBasedconfig=true.






>>>>> è       If I patch this to true then configIdKey=’






>>>>> swagger.config.id./op/services/resources/’ and no swagger entry is






>>>>> cached for this key so it will generate a new one. Again by






>>>>> patching






>>>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru


>>>>> e






>>>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”






>>>>> è       Again Scanners are cached and if usePathBasedConfig=null it


>>>> will use






>>>>> the one cached under  ‘swagger.scanner.id.default’ and this again






>>>>> returns the swagger definition for the KmopApiService interface.






>>>>> è       So patching usePathBasedConfig=true will return a new one






>>>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner






>>>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘






>>>>> which is correct. It will generate a new (but empty) Swagger object.






>>>>> è       Next Swagger2ApiListingResource will call the






>>>>> customizer.customize(s), which still isn’t putting anything new in






>>>>> the Swagger object. Should it or should the next step do this?






>>>>> è       Next BaseApiListingResource#getListing(…) is called which on


>>>> its






>>>>> turn calls getListingYamlResponse(..)






>>>>> è       The final result is a swagger.yaml document with following


>>>> content:






>>>>>    swagger: "2.0"






>>>>>       info:






>>>>>         license:






>>>>>           name: "Apache 2.0 License"






>>>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html






>>>>>       basePath: "/op/services/resources"






>>>>>        So basically an empty swagger file.






>>>>> d)      The usePathBasedConfig is derived from the ServletConfig


>>>> parameter ‘






>>>>> swagger.use.path.based.config’. Without this parameter set to true






>>>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger






>>>>> object.* So should this be set on the declaration of the






>>>>> CXFServlet** in web.xml?*






>>>>> The majority in this processing happens in the library






>>>>> swagger-jaxrs-v1.6.10 which is included as a dependency on


>>>> cxf-rt-rs-service-description-swagger.






>>>>> Even if I patch usePathBasedConfig=true about everywhere where I






>>>>> met this it still doesn’t generate a correct swagger.yaml. Am I






>>>>> still missing some configuration parameter?






>>>>> Any suggestions on how to resolve this would be welcome.






>>>>> Regards,






>>>>> J.P. Urkens










































>>>>> <<...>> <<...>>






>>>>> -----Original Message-----






>>>>> From: Andriy Redko <dr...@gmail.com>






>>>>> Sent: maandag 8 mei 2023 23:15






>>>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev






>>>>> List <












>>>>> Subject: Re: How to setup multiple JAXRS server endpoints






>>>>> Hi Jean,






>>>>> Indeed the way you would like to do that is somewhat tricky.






>>>>>> So I tried to keep the @Path declaration on the interface classes


>>>>>> but






>>>>> changed them to @Path(“”). That does seems to work except the






>>>>> swagger stuff no longer correctly works.






>>>>> This is one of the possible options but OpenAPI/Swagger gets






>>>>> confused for a






>>>>> reason: the path is now implicit (not in the spec).






>>>>> So how about this option:






>>>>>  - use only one JAX-RS server (address "/")






>>>>>  - host both resources but use @Path("accounts") and






>>>>> @Path("resources") on them respectively










>>>>> I see that for @Path("accounts") you need to apply the






>>>>> "kmopApiAuthorizationFilter", that could be done using






>>>>> DynamicFeature [1], [2]. If this is not the option and you would






>>>>> prefer to use 2 separate JAX-RS servers, you may need to provide






>>>>> your own instance of Swagger2Customizer [3], [4] which allows to






>>>>> transform the OpenAPI/Swagger on the fly. Please let me know if


>>>>> that


>>>> would it work for you, thank you.






>>>>> [1]






>>>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic


>>>>> F






>>>>> eature.html






>>>>> [2]






>>>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born


>>>>> -






>>>>> equal.html






>>>>> [3]






>>>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger


>>>>> /






>>>>> Swagger2Customizer.html






>>>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has






>>>>> customizer






>>>>> property)










>>>>> Best Regards,






>>>>>     Andriy Redko






>>>>>> Hi Andriy,






>>>>>> I am again getting into trouble with server endpoint declarations.






>>>>>> Now






>>>>> because I am adding additional JAX-RS endpoints.






>>>>>> The issue is with:






>>>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration
>>>>>> in






>>>>> combination with






>>>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the
>>>>>> web.xml






>>>>> in combination with






>>>>>> 3.      The @Path declaration in the interface class in combination
>>>>>> with






>>>>>> 4.      The @Path declaration on the interface method in
>>>>>> combination
>>> with






>>>>>> So what I had is that my web application deployed under baseUlr 'op'






>>>>>> had






>>>>> one JAXRS server endpoint with declarations like:






>>>>>> 1.      <jaxrs:server id="restServer"






>>>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">






>>>>>> 2.      <url-pattern>/services/*</url-pattern>






>>>>>> 3.      @Path("accounts") on the public interface class






>>>>>> 4.      @Path("/{authorisationId}/customerFund") on the
>>>>>> customerFund






>>>>> interface method






>>>>>> A valid API call would thus be e.g.:






>>>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/c
>>>>>> u
>>>>>> s


>>>>>> t






>>>>>> o






>>>>>> merFund






>>>>>> And this works correctly.






>>>>>> We're now introducing additional JAX-RS service endpoints and now
>>>>>> I






>>>>>> am






>>>>> running into problems. This second endpoint was declared with:






>>>>>> 1.      <jaxrs:server id="resourceServer"






>>>>> basePackages="be.dvtm.aeo.op.resources" address="/">






>>>>>> 2.      <url-pattern>/services/*</url-pattern>






>>>>>> 3.      @Path("resources") on the public interface class






>>>>>> 4.      @Path("/NACE") on the NACE interface method






>>>>>> So here a valid API call woud be:






>>>>> https://<hostname>:<port>/op/services/resources/NACE.






>>>>>> The problem is that I can not declare two <jaxrs:server> entries


>>>>>> with






>>>>>> the






>>>>> same ‘address’ as it throws the exception:






>>>>>> Caused by:
>>>>>> org.apache.cxf.service.factory.ServiceConstructionException:






>>>>> There is an endpoint already running on /.






>>>>>>  So I tried changing the addresses to:






>>>>>> ·       address=”accounts” for the restServer






>>>>>> ·       address=”resources” for the resourceServer






>>>>>> But to keep the API-call URLs the same I removed the @Path






>>>>>> declaration on






>>>>> the interface classes. By doing so the <jaxrs:server> bean






>>>>> declarations no longer loads successfully.






>>>>>> So I tried to keep the @Path declaration on the interface classes


>>>>>> but






>>>>> changed them to @Path(“”). That does seems to work except the






>>>>> swagger stuff no longer correctly works.






>>>>>> So what is the decent way to setup multiple JAX-RS server
>>>>>> endpoints






>>>>>> where






>>>>> each server has its own configuration regarding supported features:






>>>>>> ·       own validation






>>>>>> ·       own object and exception mappings






>>>>>> ·       own swagger file generation






>>>>>> ·       own logging (in separate file if possible)






>>>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in






>>>>>> cooperation






>>>>> with swager-ui v4.5.0.






>>>>>> Below the declarations of my endpoints <<...>> Thanks for any advice.






>>>>>> Regards,






>>>>>> J.P. Urkens






>>>>>> -----Original Message-----






>>>>>> From: Andriy Redko <dr...@gmail.com>






>>>>>> Sent: zaterdag 18 juni 2022 1:12






>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;






>>>>>> issues@cxf.apache.org; dev@cxf.apache.org






>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi
>>>>>> Jean,






>>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'






>>>>>> Correct, so in the relative form like address="/<something>", the






>>>>>> JAX-RS






>>>>> endpoint path would be:






>>>>>>     <baseUrl>/<servlet path






mapping>>>>>>>/<address>/[@ApplicationPath]/[@Path]






>>>>>> The @ApplicationPath is optional in this case.






>>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'






>>>>>> The JAX-WS is very different from JAX-RS, essentially the action






>>>>>> comes






>>>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/






>>>>> (@Path / @ApplicationPath are not relevant there).






>>>>>>> Question: Because now address="/" is set for the jaxrs:server
>>>>>>> will






>>>>>>> it






>>>>>>> also inspect requests targeted for the jaxws service as those






>>>>>>> requests have start with the same path '/<basePath>/services/...






>>>>>> This is a good question, I have not done it myself but I think it






>>>>>> should






>>>>> work:






>>>>>> the servlet dispatches according to registered services, in this






>>>>>> regard






>>>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?


>>>> Thank you.






>>>>>> Best Regards,






>>>>>>     Andriy Redko






>>>>>>> Hi Andriy,






>>>>>>> Using address="/" seems to work but still I don't understand how


>>>>>>> the






>>>>>>> following work together:






>>>>>>>  - path specification in servlet mapping for the CXF servlet






>>>>>>> (org.apache.cxf.transport.servlet.CXFServlet)






>>>>>>>  - the 'address' attribute on the jaxrs:server bean declaration






>>>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the






>>>>>>> service API description Say I've two services with (relateive to


>>>>>>> the






>>>>>>> host) url's:






>>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'






>>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'






>>>>>>> How do I configure above 3 aspects? Currently I have (working):






>>>>>>> 1.for the jaxrs:server endpoint:






>>>>>>>         - servlet path mapping: '/services/*'






>>>>>>>                - jaxrs-server address attribute: address="/"






>>>>>>>                - @Path annotation: @Path("service1") 2.For the


>>>>>>> jaxws






>>>>>>> service endpoint:






>>>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS






>>>>>>> requests are handleb by the same CXF servle)






>>>>>>>                - jaxws:endpoint server address attribute:






>>>>>>> address="/service2"






>>>>>>>                - @WebService(name="service2") A correct request
>>>>>>> for






>>>>>>> '1' would be '/basePath>/services/service1/<ID>'.






>>>>>>> A correct request for '2' would be '/basePath>/services/service2'.






>>>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect
>>>>>>> to:






>>>>>>>         - the server address attribute






>>>>>>>         - The API annotation (@Path or @Webservice) The JAXWS


>>>>>>> server






>>>>>>> address attribute doesn't seem to interfere with the @Webservice






>>>>>>> annotation. While the jaxrs server address attribute does seem to






>>>>>>> interfere with the @Path annotation. I would have expected the


>>>>>>> jaxrs






>>>>>>> server aspects to be configured as:






>>>>>>>         - servlet path mapping: '/services/*'






>>>>>>>                - jaxrs-server address attribute: address="/service1"






>>>>>>>                - @Path annotation: @Path("service1") but then a






>>>>>>> valid






>>>>>>> request would be






>>>>>>>> /services/service1/service1/<ID>'.






>>>>>>> For both the 'address' attribute is relative to the servlet path.






>>>>>>> The @Path Javadoc mentions that this path is relative to the






>>>>>>> ApplicationPath which thus seems to be relative to the
>>>>>>> jaxrs-server






>>>>>>> address attribute. As for @Webservice it doesnn't seem to be






>>>>>>> url-path






>>>>> related.






>>>>>>> Question: Because now address="/" is set for the jaxrs:server
>>>>>>> will






>>>>>>> it






>>>>>>> also inspect requests targeted for the jaxws service as those






>>>>>>> requests have start with the same path '/<basePath>/services/...'.






>>>>>>> Albeit somewhat confusing.






>>>>>>> J.P.






>>>>>>> -----Original Message-----






>>>>>>> From: Andriy Redko <dr...@gmail.com>






>>>>>>> Sent: dinsdag 14 juni 2022 1:08






>>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;






>>>>>>> issues@cxf.apache.org; dev@cxf.apache.org






>>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi
>>>>>>> Jean,






>>>>>>> Indeed, the jaxrs:server does not expect address to be omitted,
>>>>>>> you






>>>>>>> could use the "/" (and I believe an empty string would also make
>>>>>>> it):






>>>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...






>>>>>>> </jaxrs:server>






>>>>>>> Thank you.






>>>>>>> Hope it helps.






>>>>>>> Best Regards,






>>>>>>>     Andriy Redko






>>>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean






>>>>>>>> declarations






>>>>>>>> like:






>>>>>>>>      <jaxrs:server id="restServer" basePackages="xxx">






>>>>>>>>            <jaxrs:serviceBeans>






>>>>>>>>                 <ref bean="TestApi" />






>>>>>>>>            </jaxrs:serviceBeans>






>>>>>>>>            <jaxrs:providers>






>>>>>>>>                 <…/>






>>>>>>>>            </jaxrs:providers>






>>>>>>>>            <jaxrs:features>






>>>>>>>>                 <… />






>>>>>>>>            </jaxrs:features>






>>>>>>>>            <jaxrs:inInterceptors>






>>>>>>>>                 <… />






>>>>>>>>            </jaxrs:inInterceptors>






>>>>>>>>            <jaxrs:outInterceptors>*






>>>>>>>>                 <**…**/>*






>>>>>>>>            </jaxrs:outInterceptors>*






>>>>>>>>      </jaxrs:server>










>>>>>>>> Here my “TestApi” bean interface is declared like:






>>>>>>>>       @Path("accounts")






>>>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)






>>>>>>>>        @Produces(MediaType.*APPLICATION_JSON*)






>>>>>>>>        public interface TestApi {






>>>>>>>>          …






>>>>>>>>        }






>>>>>>>> And CXF is triggered via a servlet configuration like:






>>>>>>>>      <servlet>






>>>>>>>>              <display-name>CXF Servlet</display-name>






>>>>>>>>              <servlet-name>CXFServlet</servlet-name>






>>>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</serv
>>>>>>>> l
>>>>>>>> e






>>>>>>>> t












>>>>>>>>        </servlet>






>>>>>>>>        <servlet-mapping>






>>>>>>>>              <servlet-name>CXFServlet</servlet-name>






>>>>>>>>              <url-pattern>/services/*</url-pattern>






>>>>>>>>        </servlet-mapping>










>>>>>>>> Because I’ve got the @Path declaration on the interface type
>>>>>>>> I’ve






>>>>>>>> omitted






>>>>>>>> the address=”accounts” attribute on the jaxrs:server declaration






>>>>>>>> since otherwise






>>>>>>>> I noticed that the server would be listening to






>>>>>>>> /basepath/services/ accounts/accounts/…).






>>>>>>>> Now this configuration works perfectly, only when shutting down






>>>>>>>> the application server cxf calls






>>>>>>>>         ServerImpl#destroy()






>>>>>>>> which delegates (via Obeservable) to






>>>>>>>> AbstractHTTPDestination#deactivate()






>>>>>>>> which calls






>>>>>>>> registry.removeDestination(path).






>>>>>>>> This path is null (no ‘address’ specified on jaxrs:server






>>>>>>>> declaration) and results in a NPE on the registry Map.






>>>>>>>> This causes an unclean shutdown of my server.






>>>>>>>> Is this an error in cxf or is my jaxrs:server configured
>>>>>>>> incorrectly?






>>>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration






>>>>>>>> correctly interact with the @Path parameter on the API interface?






>>>>> <<...>>

RE: How to setup multiple JAXRS server endpoints

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
Yes, SwaggerUI works too!
I noticed that v2.x of swagger-jaxrs relates to OpenApi v3.1.x while my spec
is compliant with OpenApi v3.0.x, so I am going to stick with v2.1.13 which
seems to be that last version for OpenApi v3.0.x.

I thought the @Parameter only applied to input parameters ("query",
"header", "path" or "cookie" parameters), but I'll give it a try.

J.P.

-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: woensdag 12 juli 2023 22:16
To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
Subject: Re: How to setup multiple JAXRS server endpoints

Hi Jean,

That's awesome, have you got SwaggerUI working as well?

Yes, you could use 2.2.15 (we already updated to this version, no
regressions). It seems like the description applies to the whole schema
(which is the same for both properties), may be you could use @Parameter
instead:

@Parameter(description="The description I want for prop1")

Thank you.

Best Regards,
    Andriy Redko

> Hi Andriy,
> After having migrated everything to "io.swagger.v3.oas.annotations.*" the
> swagger endpoints for each of my services became active.
> So far so good, but I do notice that there are discrepancies when
> annotating models, e.g.:
>  public class Model1 {
>   @Schema(description="The description I want for prop1")
>    private Model2 prop1;
>   @Schema(description="The description I want for prop2")
>    private Model2 prop2;
>   ...
> }
> When I generate the openapi.[json|yaml] specification I see that both
> prop1 and prop2 have a reference to the schema component "Model2" with
> description ' The description I want for prop2' which is inappropriate for
> 'prop1'.
> It is not unlikely to have multiple properties within one Model that are
> of the same class but are semantically used in a different context. E.g.
> something as simple as a ShipmentOrder having two 'Address' properties
> 'from' and 'to' would result in wrong API documentation.
> I am aware it has nothing to do with CXF but rather with
> swagger-jaxrs2-vx.y.z.jar and depending libraries. CXF-3.5.6 has
> dependency on swagger-jaxrs2-2.1.13.jar. Would it be an issue to replace
> this dependency with e.g. swagger-jaxrs2-2.2.15.jar (latest stable release
> according to maven central repo)?
> J.P.
> -----Original Message-----
> From: Jean Pierre URKENS <je...@devoteam.com>
> Sent: woensdag 12 juli 2023 8:25
> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org'
> <de...@cxf.apache.org>
> Subject: RE: How to setup multiple JAXRS server endpoints I seem to be
> mistaken here, the endpoint was loaded (I did a manual HTTP GET test to
> the endpoint to verify this) although no breakpoints where hit during
> startup.
> I am first going to complete the migration to
> "io.swagger.v3.oas.annotations.*" annotations for all endpoints and then I
> am going to test again.
> The application is composed of libraries, some of which use SLF4J but most
> use LOG4J for logging.
> J.P.

> -----Original Message-----
> From: Andriy Redko <dr...@gmail.com>
> Sent: woensdag 12 juli 2023 1:13
> To: Jean Pierre URKENS <je...@devoteam.com>;
> dev@cxf.apache.org
> Subject: Re: How to setup multiple JAXRS server endpoints Hi Jean, The
> OpenApiFeature$Portable#initiliaze(…) should definitely be called
> (otherwise you shouldn't even see the openapi.json endpoint), so I am not
> sure why these are not triggering for you.
>
> For logging, it seems like you are using SLF4J
> (org.apache.cxf.common.logging.Slf4jLogger),
> and also reload4j (aka log4j), why do you need both?
> Thank you.
> Best Regards,
>     Andriy Redko
JPU>> After some code investigation:


JPU>> OpenApiFeature implements SwaggerUiSupport and in its
JPU>> portable#registerSwaggerUiResources(…) method it will call
JPU>> SwaggerUiSupport#getSwaggerUi(…) which will register the
SwaggerUiService.


JPU>> I have put breakpoints on:
JPU>>    - OpenApiFeature$Portable#initiliaze(…)
JPU>>    - SwaggerUiService constructor
JPU>>    - SwaggerUiSupport#getSwaggerUi(…)


JPU>> but none of them are hit when starting my application?


JPU>> Although the (spring) logging shows all beans in my
JPU>> cxf-endpoints.xml have been created?
JPU>> The *WADL* and *OpenAPI* endpoints to get the specification work.
JPU>> Even the actual endpoint seems to work although I didn’t hit any of
JPU>> the breakpoint?


JPU>> CXF, also doesn’t seem to log a lot, I am hardly getting any log
JPU>> entries although log level I set to DEBUG.
JPU>> My logging (except wire message logging) for cxf is setup correctly
JPU>> (I
JPU>> think):
JPU>>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line
JPU>>    ‘org.apache.cxf.common.logging.Slf4jLogger’
JPU>>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and
JPU>>    reload4j-1.2.19.jar are on the classpath
JPU>>    - the log4j.properties file contains the line:
JPU>>    ‘log4j.logger.org.apache.cxf=DEBUG’


JPU>> There are no special instructions mentioned on
JPU>> https://cxf.apache.org/docs/general-cxf-logging.html so the above
JPU>> should work (it works for all other packages I use in my application).


JPU>> J.P.
JPU>> *From:* Jean Pierre URKENS <je...@devoteam.com>
JPU>> *Sent:* dinsdag 11 juli 2023 9:58
JPU>> *To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <
dev@cxf.apache.org>>>
JPU>> *Subject:* RE: How to setup multiple JAXRS server endpoints


JPU>> Hi Andriy,


JPU>> As a test I removed all JAX-RS endpoints that use Swagger v2
JPU>> annotations from my configuration file (see attachment).
JPU>> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger v3
JPU>> annotations, using the OpenApiFeature i.o. Swagger2Feature.
JPU>> If I run my server with this configuration I only get the (working)
JPU>> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint:




JPU>> So there is some configuration missing to detect/activate the
JPU>> Swagger endpoint. When I look at the samples that come with the
JPU>> distribution of CXF (I am using v3.5.6) nothing special seems to be
configured to activate this?
JPU>> Do you have any idea how the SwaggerUiService is picked up when
loading?


JPU>> J.P.


JPU>> -----Original Message-----
JPU>> From: Andriy Redko <dr...@gmail.com>
JPU>> Sent: dinsdag 11 juli 2023 3:44
JPU>> To: Jean Pierre URKENS <je...@devoteam.com>;
JPU>> dev@cxf.apache.org
JPU>> Subject: Re: How to setup multiple JAXRS server endpoints


JPU>> Hi Jean,


JPU>> I guess you figured one issue, swagger.json -> openapi.json, but to
JPU>> be honest we have never tested or envisioned the application that
JPU>> would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same time, I
JPU>> am afraid this is just not supported. You may get things back on
JPU>> track when going with OpenAPI 3.0 for all services.


JPU>> Thank you.


JPU>> Best Regards,
JPU>>     Andriy Redko




>>> Hi Andriy,






>>> I am trying to trace the difference in handling with another
>>> application where I’ve got only one CXF service endpoint that uses
>>> swagger v3 openapi annotations.


>>> There I see that when handling the Swagger page request (
>>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json) the
>>> JAXRSInInterceptor is calling:






>>> *JAXRSUtils.**getRootResources*(Message message)






>>> It contains 4 entries:


>>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint
>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource
>>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService














>>> On the application described below with the service ‘oidcsim’ when
>>> calling the swagger page request
>>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the
>>> result of the getRootResources doesn’t contain the ClassResourceInfo
>>> ‘
>>> SwaggerUiService’. It only contains 3 entries:


>>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)
>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource






>>> The SwaggerUiService is the one that is configured to handle the
JPU>> ‘api-docs’
>>> path-request. Since it is missing the request is tried to match with
>>> the other two resources but fails, hence ‘NOT FOUND’ exception.






>>> I can’t trace back where these rootResources are set and why the
>>> SwaggerUiService’ isn’t listed.






>>> J.P.


>>> *From:* Jean Pierre URKENS <je...@devoteam.com>
>>> *Sent:* maandag 10 juli 2023 13:43
>>> *To:* 'Andriy Redko' <dr...@gmail.com>
>>> *Subject:* RE: How to setup multiple JAXRS server endpoints






>>> Andriy,






>>> I am trying to switch from Swagger v2 to OpenApi v3 annotations
>>> basically because my starting point is an OpenApi v3.0.7 yaml file
>>> description and OpenAPI seems to be the way forward.


>>> For applications where I have only one CXF JAX-RS endpoint exposed I
>>> had no problems converting. However as soon as there are multiple
>>> endpoints I run into troubles.






>>> So, to recall, I've an application exposing 3 JAX-RS endpoints that
>>> where previously annotated with swagger v2 annotations (i.e. package
>>> io.swagger.annotations.*) which I migrated to


>>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*). In
>>> accordance I altered my CXF JAX-RS endpoint configuration from (only
>>> showing relevant parts, see attachment for full setup):






>>>                <!-- CXF Swagger2Feature -->


>>>                <bean id="SwaggerUiConfigOidcApi"
>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">


>>>                               <property name="queryConfigEnabled"


>>>                               <property name="url"
>>> value="/op/services/oidcsim/swagger.yaml"/>


>>>                </bean>


>>>                <bean id="Swagger2FeatureOidcApi"
>>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">


>>>                               <property name="basePath"
>>> value="/op/services/oidcsim"/>


>>>                               <property name="usePathBasedConfig"


>>>                               <property name="resourcePackage"
>>> value="be.dvtm.aeo.op.oidc"/>


>>>                               <property name="supportSwaggerUi"


>>>                               <property name="swaggerUiConfig"
>>> ref="SwaggerUiConfigOidcApi"/>


>>>                </bean>


>>>                <jaxrs:server id="OidcProviderApiServer"
>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">


>>>                               ....


>>>                               <jaxrs:features>


>>>                                              <ref
>>> bean="Swagger2FeatureOidcApi" />


>>>                               </jaxrs:features>


>>>                               ...


>>>                </jaxrs:server>






>>> TO:


>>>                <!-- CXF OpenAPIFeature -->


>>>                <bean id="OidcSwaggerUiConfig"
>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">


>>>                               <property name="queryConfigEnabled"


>>>                               <property name="url"
>>> value="openapi.json"/>


>>>                </bean>


>>>                <bean id="OidcOpenApiFeature"
>>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">


>>>                               <property name="supportSwaggerUi"


>>>                               <property name="swaggerUiConfig"
>>> ref="OidcSwaggerUiConfig"/>


>>>                               <property name="swaggerUiVersion"


>>>                               <property name="scan" value="false"/>


>>>                               <property name="useContextBasedConfig"


>>>                               <property name="resourcePackages"
>>> value="be.dvtm.aeo.op.oidc"/>


>>>                </bean>


>>>                <jaxrs:server id="OidcProviderApiServer"
>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">


>>>                               ....


>>>                               <jaxrs:features>


>>>                                              <ref
JPU>> bean="OidcOpenApiFeature"


>>>                               </jaxrs:features>


>>>                               ...


>>>                </jaxrs:server>










>>> Now when starting my application and navigating to the root part "
>>> http://localhost:localPort/op/services" I get an overview of all my
>>> endpoints:






>>> Now there are 3 RESTful service endpoints setup:


>>>    1. ‘oidcsim’ which I switched to swagger v3 annotations
>>>    2. ‘openapi’ currently still swagger v2 annotations
>>>    3. ‘sdx’ currently still swagger v2 annotations






>>> all endpoints work except for the ‘swagger endpoint address for the
>>> oidcsim
>>> endpoint:
>>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services/o
>>> i
>>> dcsim/swagger.json


>>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*
>>> endpoint of the oidcsim resource. I am getting an error (the value of
>>> the ‘url’ query parameter isn’t relevant):






>>>         “WebApplicationException has been caught, status: 404,
>>> message: HTTP 404 Not Found”






>>> When I try (without the ‘/oidcsim’ context):
>>> http://l-p53-008:8081/op/services/api-docs I get:


>>>                “No service was found.”






>>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs
>>> doesn’t exist, where as the endpoint
>>> http://l-p53-008:8081/op/services/api-docs does exist but no service
JPU>> description is found?


>>> Of course my intention is to get working, as previously with the
>>> swagger v2 setup for which I then specifically added the
>>> *Swagger2Feature* config
>>> parameters:


>>>                               <property name="basePath"
>>> value="/op/services/oidcsim"/>


>>>                               <property name="usePathBasedConfig"






>>> But I don’t find the according configuration options for the
>>> *OpenApiFeature* class or whether I should configure this in another
>>> way.






>>> Any suggestions on this?






>>> Regards,






>>> J.P.










>>> -----Original Message-----
>>> From: Andriy Redko <dr...@gmail.com>
>>> Sent: donderdag 25 mei 2023 2:27
>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>>> dev@cxf.apache.org
>>> Subject: Re: How to setup multiple JAXRS server endpoints






>>> Hi Jean,






>>> You may run into Swagger JAX-RS scanner limitations, as far as I can
>>> tell - it checks class annotations for SwaggerDefinition, does not
>>> traverse the hierarchy [1].






>>> [1]
>>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-
>>> j
>>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194






>>> Best Regards,


>>>     Andriy Redko






>>>>  RE: How to setup multiple JAXRS server endpoints






>>>> Still one question );






>>>> The generated swagger file doesn’t take into account the


>>>> @SwaggerDefintion on my interface classes?






>>>> As a test I looked at


>>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma


>>>> in/release/samples/jax_rs/description_swagger2_web**


>>>> and** modified** sample2*


>>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma


>>>> in/release/samples/jax_rs/description_swagger2_web


>>>> and modified sample2> as follows:






>>>>    @Path("/sample2")






>>>>       @Api(value = "/sample2",authorizations=


>>>>       {@Authorization(value="bearer")},description = "Sample2
>>> (modified) JAX-RS


>>>>       service with Swagger documentation")






>>>>       @SwaggerDefinition(






>>>>               info = @Info(






>>>>                       description = "Sample2 server",






>>>>                       version="1.0",






>>>>                       title = "Test2",






>>>>                       contact = @Contact(name = "J.P. Urkens",email = "


>>>>       *jean-pierre.urkens@devoteam.com* <
>>> jean-pierre.urkens@devoteam.com>


>>>>       ")),






>>>>               securityDefinition =


>>>>       @SecurityDefinition(apiKeyAuthDefinitions=


>>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="A
>>> u
>>> thorization",description="Use*


>>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer


>>>>       &lt;accessToken&gt;'")})






>>>>       )






>>>>       public class Sample2 {...}






>>>> This correctly generates the ‘securityDefintions’ in the swagger file.






>>>> If include the same @SwaggerDefinition and the authorizations on


>>>> the @Api annotation as above in my interface classes then the


>>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?






>>>> Any idea what I might be missing?






>>>> Regards,






>>>> J.P.






>>>> -----Original Message-----


>>>> From: Jean Pierre URKENS <je...@devoteam.com>


>>>> Sent: dinsdag 23 mei 2023 12:52


>>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <




>>>> Subject: RE: How to setup multiple JAXRS server endpoints






>>>> Hi Andriy,






>>>> I added the parameter usePathBasedConfig=true to the


>>>> Swagger2Feature bean declarations but still it does generate an


>>>> empty swagger.yaml for interfaces KmopResources and


>>>> KmopDienstverlener although I noticed that for these interfaces the


>>>> @Path() annotation was commented out (as I included it in the


>>>> server declaration). After providing an empty @Path("") declaration
>>>> on
>>> the API interface classes everything worked.






>>>> Thanks for the support.






>>>> -----Original Message-----






>>>> From: Andriy Redko <dr...@gmail.com>






>>>> Sent: dinsdag 23 mei 2023 3:42






>>>> To: Jean Pierre URKENS <je...@devoteam.com>;


>>>> dev@cxf.apache.org






>>>> Subject: Re: How to setup multiple JAXRS server endpoints






>>>> Hi Jean,






>>>> The main problem to configure Swagger property in your particular


>>>> case is that the server address is not "known" or "introspectable"
>>>> for
>>> Swagger.


>>>> Intuitively, it has to be set manually using basePath to the,


>>>> essentially, the server address






>>>> part:






>>>>  - /op/services/accounts






>>>>  - /op/services/resources






>>>>  - /op/services/dienstverlener






>>>> You could read more about other Swagger properties you have asked here:


>>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte


>>>> gration-and-Configuration#configuration-properties






>>>> You definitely need to set usePathBasedConfig to "true" otherwise


>>>> you will see the same Swagger specs for all servers. We have a


>>>> sample here which uses 2 jaxrs:server






>>>> instances:


>>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai


>>>> n/release/samples/jax_rs/description_swagger2_web






>>>> Regarding SwaggerUI, I think the value for each of those should be


>>>> set to,


>>>> respectively:






>>>>  - /op/services/accounts/swagger.yaml






>>>>  - /op/services/resources/swagger.yaml






>>>>  - /op/services/dienstverlener/swagger.yaml






>>>> I believe this is matching your settings already, except the


>>>> usePathBasedConfig part. The example referred above could be


>>>> helpful, my apologies if I missed something, there are quite a lot


>>>> of questions :-) The fact that the generated Swagger specification


>>>> is empty is unexpected - it should not happen when JAX-RS resources
>>> are properly configured.






>>>> Thank you.






>>>> Best Regards,






>>>>     Andriy Redko






>>>>>  RE: How to setup multiple JAXRS server endpoints






>>>>> Hi Andriy,






>>>>> I am not quite understanding how to correctly configure the


>>>> Swagger2Feature.






>>>>> Referring to the attached cxf-endpoints configuration I (as a


>>>>> test)






>>>>> created






>>>>> 3 JAXRS server instances:






>>>>> 1.      A* KmopApiServer* server for the*






>>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving






>>>>> requests for URI path:






>>>>>        * <protocol>**//<host:<port>/op/services/accounts*






>>>>>    ‘op’  = root path of the web application






>>>>>             ‘services’ = servlet path of the CXF-servlet






>>>>>       The address of the server is set to ‘/accounts’ and the


>>>>> @Path(…)






>>>>>       annotation on the interface class was cleared.






>>>>> 2.      A* Kmop**Resources**ApiServer* server for the*
>>> be.dvtm.aeo.op.*






>>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving






>>>>> requests for URI path:






>>>>>        * <protocol>**//<host:<port>/op/services/**resources*






>>>>> The address of the server is set to ‘/resources’ and the @Path(…)






>>>>> annotation on the interface class was cleared.






>>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*


>>>> be.dvtm.aeo.op.*






>>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving






>>>>> requests for URI path:






>>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*






>>>>> The address of the server is set to ‘/dienstverlener’ and the






>>>>> @Path(…) annotation on the interface class was cleared.






>>>>> For each of these server instances I’ve set the Swagger2Feature






>>>>> with configuration as indicated in the attached cxf-endpoints.xml.






>>>>> With regard to the configurations for the Swagger2Feature I’ve the






>>>>> following questions:






>>>>> a)      Referring to *
>>> https://cxf.apache.org/docs/swagger2feature.html*






>>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you






>>>>> clarify on the following configuration parameters:






>>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘






>>>>> /op/services’) or to the JAX-RS server instance (e.g.






>>>>> ‘/op/services/accounts’) or still something else? Is it used to






>>>>> resolve service classes or is it just for documentation in the


>>>>> swagger


>>>> file?






>>>>> *ii.    ** resourcePackage* – the description mentions ‘package names’






>>>>> while the default mentions ‘service classes’? Service 2 and 3


>>>>> above






>>>>> are within the same package (generated from the same yaml






>>>>> specification that included both interfaces).






>>>>> *iii.   ** ig**noreRoutes* – is this taken into account when






>>>>> scanAllResources=false?






>>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter
>>> value






>>>>> (cf. question ‘a’)?






>>>>> b)      What would be the correct URL to generate a swagger.yaml
>>>>> file


>>>> for






>>>>> each of the above interfaces? Initially I called:






>>>>> *i.     **


>>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*






>>>>> *ii.    **


>>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*






>>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*






>>>>> *lener/swagger.yaml*






>>>>>    All three requests delivered the same yaml specification,


>>>>> namely


>>>> the one






>>>>>       for interface* KmopApiServer*?






>>>>> c)      I tried to debug the processing of the requests under ‘b)’
>>>>> and


>>>> this






>>>>> is done by the class JAXRSInterceptor#processRequest where the






>>>>> MessageImpl object for request “ii.” looks like the one attached.






>>>>> It finds 3 resource






>>>>> classes:






>>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl






>>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource






>>>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService






>>>>> è       It matches the request to resource*


>>>> Swagger2ApiListingResource* with






>>>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*






>>>>> process(…)* method.






>>>>> è       Here it seems to go wrong. It generates a
>>> SwaggerContextService






>>>>> having basePath=/op/services/resources/,swaggerConfig=null,






>>>>> usePathBasedConfig=null and then calls






>>>>> SwaggerContextService.getSwagger()






>>>>> which returns the Swagger definition for interface KmopApiServer?






>>>>> It looks like it caches generated swagger definitions based on a






>>>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the






>>>>> same for all 3 interfaces as usePathBasedConfig=null






>>>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is






>>>>> derived from the ServletConfig parameter






>>>>> ‘swagger.use.path.based.config’.* So should this be set on the






>>>>> declaration of the CXFServlet** in web.xml?*






>>>>> è       Actually the SwaggerConfig, the JaxrsScanner and the
>>>>> generated


>>>> Swagger






>>>>> are cached using keys like






>>>>> ‘swagger.config.id.[default|baseUriPath]’, ‘






>>>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’


>>>> is only done when usePathBasedconfig=true.






>>>>> è       If I patch this to true then configIdKey=’






>>>>> swagger.config.id./op/services/resources/’ and no swagger entry is






>>>>> cached for this key so it will generate a new one. Again by






>>>>> patching






>>>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru


>>>>> e






>>>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”






>>>>> è       Again Scanners are cached and if usePathBasedConfig=null it


>>>> will use






>>>>> the one cached under  ‘swagger.scanner.id.default’ and this again






>>>>> returns the swagger definition for the KmopApiService interface.






>>>>> è       So patching usePathBasedConfig=true will return a new one






>>>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner






>>>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘






>>>>> which is correct. It will generate a new (but empty) Swagger object.






>>>>> è       Next Swagger2ApiListingResource will call the






>>>>> customizer.customize(s), which still isn’t putting anything new in






>>>>> the Swagger object. Should it or should the next step do this?






>>>>> è       Next BaseApiListingResource#getListing(…) is called which on


>>>> its






>>>>> turn calls getListingYamlResponse(..)






>>>>> è       The final result is a swagger.yaml document with following


>>>> content:






>>>>>    swagger: "2.0"






>>>>>       info:






>>>>>         license:






>>>>>           name: "Apache 2.0 License"






>>>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html






>>>>>       basePath: "/op/services/resources"






>>>>>        So basically an empty swagger file.






>>>>> d)      The usePathBasedConfig is derived from the ServletConfig


>>>> parameter ‘






>>>>> swagger.use.path.based.config’. Without this parameter set to true






>>>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger






>>>>> object.* So should this be set on the declaration of the






>>>>> CXFServlet** in web.xml?*






>>>>> The majority in this processing happens in the library






>>>>> swagger-jaxrs-v1.6.10 which is included as a dependency on


>>>> cxf-rt-rs-service-description-swagger.






>>>>> Even if I patch usePathBasedConfig=true about everywhere where I






>>>>> met this it still doesn’t generate a correct swagger.yaml. Am I






>>>>> still missing some configuration parameter?






>>>>> Any suggestions on how to resolve this would be welcome.






>>>>> Regards,






>>>>> J.P. Urkens










































>>>>> <<...>> <<...>>






>>>>> -----Original Message-----






>>>>> From: Andriy Redko <dr...@gmail.com>






>>>>> Sent: maandag 8 mei 2023 23:15






>>>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev






>>>>> List <












>>>>> Subject: Re: How to setup multiple JAXRS server endpoints






>>>>> Hi Jean,






>>>>> Indeed the way you would like to do that is somewhat tricky.






>>>>>> So I tried to keep the @Path declaration on the interface classes


>>>>>> but






>>>>> changed them to @Path(“”). That does seems to work except the






>>>>> swagger stuff no longer correctly works.






>>>>> This is one of the possible options but OpenAPI/Swagger gets






>>>>> confused for a






>>>>> reason: the path is now implicit (not in the spec).






>>>>> So how about this option:






>>>>>  - use only one JAX-RS server (address "/")






>>>>>  - host both resources but use @Path("accounts") and






>>>>> @Path("resources") on them respectively










>>>>> I see that for @Path("accounts") you need to apply the






>>>>> "kmopApiAuthorizationFilter", that could be done using






>>>>> DynamicFeature [1], [2]. If this is not the option and you would






>>>>> prefer to use 2 separate JAX-RS servers, you may need to provide






>>>>> your own instance of Swagger2Customizer [3], [4] which allows to






>>>>> transform the OpenAPI/Swagger on the fly. Please let me know if


>>>>> that


>>>> would it work for you, thank you.






>>>>> [1]






>>>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic


>>>>> F






>>>>> eature.html






>>>>> [2]






>>>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born


>>>>> -






>>>>> equal.html






>>>>> [3]






>>>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger


>>>>> /






>>>>> Swagger2Customizer.html






>>>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has






>>>>> customizer






>>>>> property)










>>>>> Best Regards,






>>>>>     Andriy Redko






>>>>>> Hi Andriy,






>>>>>> I am again getting into trouble with server endpoint declarations.






>>>>>> Now






>>>>> because I am adding additional JAX-RS endpoints.






>>>>>> The issue is with:






>>>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration
>>>>>> in






>>>>> combination with






>>>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the
>>>>>> web.xml






>>>>> in combination with






>>>>>> 3.      The @Path declaration in the interface class in combination
>>>>>> with






>>>>>> 4.      The @Path declaration on the interface method in
>>>>>> combination
>>> with






>>>>>> So what I had is that my web application deployed under baseUlr 'op'






>>>>>> had






>>>>> one JAXRS server endpoint with declarations like:






>>>>>> 1.      <jaxrs:server id="restServer"






>>>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">






>>>>>> 2.      <url-pattern>/services/*</url-pattern>






>>>>>> 3.      @Path("accounts") on the public interface class






>>>>>> 4.      @Path("/{authorisationId}/customerFund") on the
>>>>>> customerFund






>>>>> interface method






>>>>>> A valid API call would thus be e.g.:






>>>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/c
>>>>>> u
>>>>>> s


>>>>>> t






>>>>>> o






>>>>>> merFund






>>>>>> And this works correctly.






>>>>>> We're now introducing additional JAX-RS service endpoints and now
>>>>>> I






>>>>>> am






>>>>> running into problems. This second endpoint was declared with:






>>>>>> 1.      <jaxrs:server id="resourceServer"






>>>>> basePackages="be.dvtm.aeo.op.resources" address="/">






>>>>>> 2.      <url-pattern>/services/*</url-pattern>






>>>>>> 3.      @Path("resources") on the public interface class






>>>>>> 4.      @Path("/NACE") on the NACE interface method






>>>>>> So here a valid API call woud be:






>>>>> https://<hostname>:<port>/op/services/resources/NACE.






>>>>>> The problem is that I can not declare two <jaxrs:server> entries


>>>>>> with






>>>>>> the






>>>>> same ‘address’ as it throws the exception:






>>>>>> Caused by:
>>>>>> org.apache.cxf.service.factory.ServiceConstructionException:






>>>>> There is an endpoint already running on /.






>>>>>>  So I tried changing the addresses to:






>>>>>> ·       address=”accounts” for the restServer






>>>>>> ·       address=”resources” for the resourceServer






>>>>>> But to keep the API-call URLs the same I removed the @Path






>>>>>> declaration on






>>>>> the interface classes. By doing so the <jaxrs:server> bean






>>>>> declarations no longer loads successfully.






>>>>>> So I tried to keep the @Path declaration on the interface classes


>>>>>> but






>>>>> changed them to @Path(“”). That does seems to work except the






>>>>> swagger stuff no longer correctly works.






>>>>>> So what is the decent way to setup multiple JAX-RS server
>>>>>> endpoints






>>>>>> where






>>>>> each server has its own configuration regarding supported features:






>>>>>> ·       own validation






>>>>>> ·       own object and exception mappings






>>>>>> ·       own swagger file generation






>>>>>> ·       own logging (in separate file if possible)






>>>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in






>>>>>> cooperation






>>>>> with swager-ui v4.5.0.






>>>>>> Below the declarations of my endpoints <<...>> Thanks for any advice.






>>>>>> Regards,






>>>>>> J.P. Urkens






>>>>>> -----Original Message-----






>>>>>> From: Andriy Redko <dr...@gmail.com>






>>>>>> Sent: zaterdag 18 juni 2022 1:12






>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;






>>>>>> issues@cxf.apache.org; dev@cxf.apache.org






>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi
>>>>>> Jean,






>>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'






>>>>>> Correct, so in the relative form like address="/<something>", the






>>>>>> JAX-RS






>>>>> endpoint path would be:






>>>>>>     <baseUrl>/<servlet path






mapping>>>>>>>/<address>/[@ApplicationPath]/[@Path]






>>>>>> The @ApplicationPath is optional in this case.






>>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'






>>>>>> The JAX-WS is very different from JAX-RS, essentially the action






>>>>>> comes






>>>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/






>>>>> (@Path / @ApplicationPath are not relevant there).






>>>>>>> Question: Because now address="/" is set for the jaxrs:server
>>>>>>> will






>>>>>>> it






>>>>>>> also inspect requests targeted for the jaxws service as those






>>>>>>> requests have start with the same path '/<basePath>/services/...






>>>>>> This is a good question, I have not done it myself but I think it






>>>>>> should






>>>>> work:






>>>>>> the servlet dispatches according to registered services, in this






>>>>>> regard






>>>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?


>>>> Thank you.






>>>>>> Best Regards,






>>>>>>     Andriy Redko






>>>>>>> Hi Andriy,






>>>>>>> Using address="/" seems to work but still I don't understand how


>>>>>>> the






>>>>>>> following work together:






>>>>>>>  - path specification in servlet mapping for the CXF servlet






>>>>>>> (org.apache.cxf.transport.servlet.CXFServlet)






>>>>>>>  - the 'address' attribute on the jaxrs:server bean declaration






>>>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the






>>>>>>> service API description Say I've two services with (relateive to


>>>>>>> the






>>>>>>> host) url's:






>>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'






>>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'






>>>>>>> How do I configure above 3 aspects? Currently I have (working):






>>>>>>> 1.for the jaxrs:server endpoint:






>>>>>>>         - servlet path mapping: '/services/*'






>>>>>>>                - jaxrs-server address attribute: address="/"






>>>>>>>                - @Path annotation: @Path("service1") 2.For the


>>>>>>> jaxws






>>>>>>> service endpoint:






>>>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS






>>>>>>> requests are handleb by the same CXF servle)






>>>>>>>                - jaxws:endpoint server address attribute:






>>>>>>> address="/service2"






>>>>>>>                - @WebService(name="service2") A correct request
>>>>>>> for






>>>>>>> '1' would be '/basePath>/services/service1/<ID>'.






>>>>>>> A correct request for '2' would be '/basePath>/services/service2'.






>>>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect
>>>>>>> to:






>>>>>>>         - the server address attribute






>>>>>>>         - The API annotation (@Path or @Webservice) The JAXWS


>>>>>>> server






>>>>>>> address attribute doesn't seem to interfere with the @Webservice






>>>>>>> annotation. While the jaxrs server address attribute does seem to






>>>>>>> interfere with the @Path annotation. I would have expected the


>>>>>>> jaxrs






>>>>>>> server aspects to be configured as:






>>>>>>>         - servlet path mapping: '/services/*'






>>>>>>>                - jaxrs-server address attribute: address="/service1"






>>>>>>>                - @Path annotation: @Path("service1") but then a






>>>>>>> valid






>>>>>>> request would be






>>>>>>>> /services/service1/service1/<ID>'.






>>>>>>> For both the 'address' attribute is relative to the servlet path.






>>>>>>> The @Path Javadoc mentions that this path is relative to the






>>>>>>> ApplicationPath which thus seems to be relative to the
>>>>>>> jaxrs-server






>>>>>>> address attribute. As for @Webservice it doesnn't seem to be






>>>>>>> url-path






>>>>> related.






>>>>>>> Question: Because now address="/" is set for the jaxrs:server
>>>>>>> will






>>>>>>> it






>>>>>>> also inspect requests targeted for the jaxws service as those






>>>>>>> requests have start with the same path '/<basePath>/services/...'.






>>>>>>> Albeit somewhat confusing.






>>>>>>> J.P.






>>>>>>> -----Original Message-----






>>>>>>> From: Andriy Redko <dr...@gmail.com>






>>>>>>> Sent: dinsdag 14 juni 2022 1:08






>>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;






>>>>>>> issues@cxf.apache.org; dev@cxf.apache.org






>>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi
>>>>>>> Jean,






>>>>>>> Indeed, the jaxrs:server does not expect address to be omitted,
>>>>>>> you






>>>>>>> could use the "/" (and I believe an empty string would also make
>>>>>>> it):






>>>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...






>>>>>>> </jaxrs:server>






>>>>>>> Thank you.






>>>>>>> Hope it helps.






>>>>>>> Best Regards,






>>>>>>>     Andriy Redko






>>>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean






>>>>>>>> declarations






>>>>>>>> like:






>>>>>>>>      <jaxrs:server id="restServer" basePackages="xxx">






>>>>>>>>            <jaxrs:serviceBeans>






>>>>>>>>                 <ref bean="TestApi" />






>>>>>>>>            </jaxrs:serviceBeans>






>>>>>>>>            <jaxrs:providers>






>>>>>>>>                 <…/>






>>>>>>>>            </jaxrs:providers>






>>>>>>>>            <jaxrs:features>






>>>>>>>>                 <… />






>>>>>>>>            </jaxrs:features>






>>>>>>>>            <jaxrs:inInterceptors>






>>>>>>>>                 <… />






>>>>>>>>            </jaxrs:inInterceptors>






>>>>>>>>            <jaxrs:outInterceptors>*






>>>>>>>>                 <**…**/>*






>>>>>>>>            </jaxrs:outInterceptors>*






>>>>>>>>      </jaxrs:server>










>>>>>>>> Here my “TestApi” bean interface is declared like:






>>>>>>>>       @Path("accounts")






>>>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)






>>>>>>>>        @Produces(MediaType.*APPLICATION_JSON*)






>>>>>>>>        public interface TestApi {






>>>>>>>>          …






>>>>>>>>        }






>>>>>>>> And CXF is triggered via a servlet configuration like:






>>>>>>>>      <servlet>






>>>>>>>>              <display-name>CXF Servlet</display-name>






>>>>>>>>              <servlet-name>CXFServlet</servlet-name>






>>>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</serv
>>>>>>>> l
>>>>>>>> e






>>>>>>>> t












>>>>>>>>        </servlet>






>>>>>>>>        <servlet-mapping>






>>>>>>>>              <servlet-name>CXFServlet</servlet-name>






>>>>>>>>              <url-pattern>/services/*</url-pattern>






>>>>>>>>        </servlet-mapping>










>>>>>>>> Because I’ve got the @Path declaration on the interface type
>>>>>>>> I’ve






>>>>>>>> omitted






>>>>>>>> the address=”accounts” attribute on the jaxrs:server declaration






>>>>>>>> since otherwise






>>>>>>>> I noticed that the server would be listening to






>>>>>>>> /basepath/services/ accounts/accounts/…).






>>>>>>>> Now this configuration works perfectly, only when shutting down






>>>>>>>> the application server cxf calls






>>>>>>>>         ServerImpl#destroy()






>>>>>>>> which delegates (via Obeservable) to






>>>>>>>> AbstractHTTPDestination#deactivate()






>>>>>>>> which calls






>>>>>>>> registry.removeDestination(path).






>>>>>>>> This path is null (no ‘address’ specified on jaxrs:server






>>>>>>>> declaration) and results in a NPE on the registry Map.






>>>>>>>> This causes an unclean shutdown of my server.






>>>>>>>> Is this an error in cxf or is my jaxrs:server configured
>>>>>>>> incorrectly?






>>>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration






>>>>>>>> correctly interact with the @Path parameter on the API interface?






>>>>> <<...>>

Re: How to setup multiple JAXRS server endpoints

Posted by Andriy Redko <dr...@gmail.com>.
Hi Jean,

That's awesome, have you got SwaggerUI working as well?

Yes, you could use 2.2.15 (we already updated to this version, no regressions). It seems like the
description applies to the whole schema (which is the same for both properties), may be you could 
use @Parameter instead:

@Parameter(description="The description I want for prop1")

Thank you.

Best Regards,
    Andriy Redko

> Hi Andriy,
> After having migrated everything to "io.swagger.v3.oas.annotations.*" the swagger endpoints for each of my services became active.
> So far so good, but I do notice that there are discrepancies when annotating models, e.g.:
>  public class Model1 {
>   @Schema(description="The description I want for prop1")
>    private Model2 prop1;
>   @Schema(description="The description I want for prop2")
>    private Model2 prop2;
>   ...
> }
> When I generate the openapi.[json|yaml] specification I see that both prop1 and prop2 have a reference to the schema component "Model2" with description ' The description I want for prop2' which is inappropriate for 'prop1'.
> It is not unlikely to have multiple properties within one Model that are of the same class but are semantically used in a different context. E.g. something as simple as a ShipmentOrder having two 'Address' properties 'from' and 'to' would result in wrong API documentation.
> I am aware it has nothing to do with CXF but rather with swagger-jaxrs2-vx.y.z.jar and depending libraries. CXF-3.5.6 has dependency on swagger-jaxrs2-2.1.13.jar. Would it be an issue to replace this dependency with e.g. swagger-jaxrs2-2.2.15.jar (latest stable release according to maven central repo)?
> J.P.
> -----Original Message-----
> From: Jean Pierre URKENS <je...@devoteam.com>
> Sent: woensdag 12 juli 2023 8:25
> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <de...@cxf.apache.org>
> Subject: RE: How to setup multiple JAXRS server endpoints
> I seem to be mistaken here, the endpoint was loaded (I did a manual HTTP GET test to the endpoint to verify this) although no breakpoints where hit during startup.
> I am first going to complete the migration to "io.swagger.v3.oas.annotations.*" annotations for all endpoints and then I am going to test again.
> The application is composed of libraries, some of which use SLF4J but most use LOG4J for logging.
> J.P. 

> -----Original Message-----
> From: Andriy Redko <dr...@gmail.com>
> Sent: woensdag 12 juli 2023 1:13
> To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
> Subject: Re: How to setup multiple JAXRS server endpoints
> Hi Jean,
> The OpenApiFeature$Portable#initiliaze(…) should definitely be called (otherwise you shouldn't even see the openapi.json endpoint), so I am not sure why these are not triggering for you.
>        
> For logging, it seems like you are using SLF4J (org.apache.cxf.common.logging.Slf4jLogger),
> and also reload4j (aka log4j), why do you need both?
> Thank you.
> Best Regards,
>     Andriy Redko
JPU>> After some code investigation: 


JPU>> OpenApiFeature implements SwaggerUiSupport and in its
JPU>> portable#registerSwaggerUiResources(…) method it will call
JPU>> SwaggerUiSupport#getSwaggerUi(…) which will register the SwaggerUiService. 


JPU>> I have put breakpoints on:
JPU>>    - OpenApiFeature$Portable#initiliaze(…)
JPU>>    - SwaggerUiService constructor
JPU>>    - SwaggerUiSupport#getSwaggerUi(…) 


JPU>> but none of them are hit when starting my application? 


JPU>> Although the (spring) logging shows all beans in my
JPU>> cxf-endpoints.xml have been created?
JPU>> The *WADL* and *OpenAPI* endpoints to get the specification work.
JPU>> Even the actual endpoint seems to work although I didn’t hit any of
JPU>> the breakpoint? 


JPU>> CXF, also doesn’t seem to log a lot, I am hardly getting any log
JPU>> entries although log level I set to DEBUG.
JPU>> My logging (except wire message logging) for cxf is setup correctly
JPU>> (I
JPU>> think):
JPU>>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line
JPU>>    ‘org.apache.cxf.common.logging.Slf4jLogger’
JPU>>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and
JPU>>    reload4j-1.2.19.jar are on the classpath
JPU>>    - the log4j.properties file contains the line:
JPU>>    ‘log4j.logger.org.apache.cxf=DEBUG’ 


JPU>> There are no special instructions mentioned on
JPU>> https://cxf.apache.org/docs/general-cxf-logging.html so the above
JPU>> should work (it works for all other packages I use in my application). 


JPU>> J.P.
JPU>> *From:* Jean Pierre URKENS <je...@devoteam.com>
JPU>> *Sent:* dinsdag 11 juli 2023 9:58
JPU>> *To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <
dev@cxf.apache.org>>>
JPU>> *Subject:* RE: How to setup multiple JAXRS server endpoints 


JPU>> Hi Andriy, 


JPU>> As a test I removed all JAX-RS endpoints that use Swagger v2
JPU>> annotations from my configuration file (see attachment).
JPU>> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger v3
JPU>> annotations, using the OpenApiFeature i.o. Swagger2Feature.
JPU>> If I run my server with this configuration I only get the (working)
JPU>> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint: 




JPU>> So there is some configuration missing to detect/activate the
JPU>> Swagger endpoint. When I look at the samples that come with the
JPU>> distribution of CXF (I am using v3.5.6) nothing special seems to be configured to activate this?
JPU>> Do you have any idea how the SwaggerUiService is picked up when loading? 


JPU>> J.P. 


JPU>> -----Original Message-----
JPU>> From: Andriy Redko <dr...@gmail.com>
JPU>> Sent: dinsdag 11 juli 2023 3:44
JPU>> To: Jean Pierre URKENS <je...@devoteam.com>;
JPU>> dev@cxf.apache.org
JPU>> Subject: Re: How to setup multiple JAXRS server endpoints 


JPU>> Hi Jean, 


JPU>> I guess you figured one issue, swagger.json -> openapi.json, but to
JPU>> be honest we have never tested or envisioned the application that
JPU>> would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same time, I
JPU>> am afraid this is just not supported. You may get things back on
JPU>> track when going with OpenAPI 3.0 for all services. 


JPU>> Thank you. 


JPU>> Best Regards,
JPU>>     Andriy Redko 




>>> Hi Andriy, 






>>> I am trying to trace the difference in handling with another
>>> application where I’ve got only one CXF service endpoint that uses
>>> swagger v3 openapi annotations. 


>>> There I see that when handling the Swagger page request (
>>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json) the
>>> JAXRSInInterceptor is calling: 






>>> *JAXRSUtils.**getRootResources*(Message message) 






>>> It contains 4 entries: 


>>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint
>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource
>>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService 














>>> On the application described below with the service ‘oidcsim’ when
>>> calling the swagger page request
>>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the
>>> result of the getRootResources doesn’t contain the ClassResourceInfo
>>> ‘
>>> SwaggerUiService’. It only contains 3 entries: 


>>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)
>>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource 






>>> The SwaggerUiService is the one that is configured to handle the
JPU>> ‘api-docs’
>>> path-request. Since it is missing the request is tried to match with
>>> the other two resources but fails, hence ‘NOT FOUND’ exception. 






>>> I can’t trace back where these rootResources are set and why the
>>> SwaggerUiService’ isn’t listed. 






>>> J.P. 


>>> *From:* Jean Pierre URKENS <je...@devoteam.com>
>>> *Sent:* maandag 10 juli 2023 13:43
>>> *To:* 'Andriy Redko' <dr...@gmail.com>
>>> *Subject:* RE: How to setup multiple JAXRS server endpoints 






>>> Andriy, 






>>> I am trying to switch from Swagger v2 to OpenApi v3 annotations
>>> basically because my starting point is an OpenApi v3.0.7 yaml file
>>> description and OpenAPI seems to be the way forward. 


>>> For applications where I have only one CXF JAX-RS endpoint exposed I
>>> had no problems converting. However as soon as there are multiple
>>> endpoints I run into troubles. 






>>> So, to recall, I've an application exposing 3 JAX-RS endpoints that
>>> where previously annotated with swagger v2 annotations (i.e. package
>>> io.swagger.annotations.*) which I migrated to 


>>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*). In
>>> accordance I altered my CXF JAX-RS endpoint configuration from (only
>>> showing relevant parts, see attachment for full setup): 






>>>                <!-- CXF Swagger2Feature --> 


>>>                <bean id="SwaggerUiConfigOidcApi"
>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig"> 


>>>                               <property name="queryConfigEnabled" 


>>>                               <property name="url"
>>> value="/op/services/oidcsim/swagger.yaml"/> 


>>>                </bean> 


>>>                <bean id="Swagger2FeatureOidcApi"
>>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature"> 


>>>                               <property name="basePath"
>>> value="/op/services/oidcsim"/> 


>>>                               <property name="usePathBasedConfig" 


>>>                               <property name="resourcePackage"
>>> value="be.dvtm.aeo.op.oidc"/> 


>>>                               <property name="supportSwaggerUi" 


>>>                               <property name="swaggerUiConfig"
>>> ref="SwaggerUiConfigOidcApi"/> 


>>>                </bean> 


>>>                <jaxrs:server id="OidcProviderApiServer"
>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim"> 


>>>                               .... 


>>>                               <jaxrs:features> 


>>>                                              <ref
>>> bean="Swagger2FeatureOidcApi" /> 


>>>                               </jaxrs:features> 


>>>                               ... 


>>>                </jaxrs:server> 






>>> TO: 


>>>                <!-- CXF OpenAPIFeature --> 


>>>                <bean id="OidcSwaggerUiConfig"
>>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig"> 


>>>                               <property name="queryConfigEnabled" 


>>>                               <property name="url"
>>> value="openapi.json"/> 


>>>                </bean> 


>>>                <bean id="OidcOpenApiFeature"
>>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature"> 


>>>                               <property name="supportSwaggerUi" 


>>>                               <property name="swaggerUiConfig"
>>> ref="OidcSwaggerUiConfig"/> 


>>>                               <property name="swaggerUiVersion" 


>>>                               <property name="scan" value="false"/> 


>>>                               <property name="useContextBasedConfig" 


>>>                               <property name="resourcePackages"
>>> value="be.dvtm.aeo.op.oidc"/> 


>>>                </bean> 


>>>                <jaxrs:server id="OidcProviderApiServer"
>>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim"> 


>>>                               .... 


>>>                               <jaxrs:features> 


>>>                                              <ref
JPU>> bean="OidcOpenApiFeature" 


>>>                               </jaxrs:features> 


>>>                               ... 


>>>                </jaxrs:server> 










>>> Now when starting my application and navigating to the root part "
>>> http://localhost:localPort/op/services" I get an overview of all my
>>> endpoints: 






>>> Now there are 3 RESTful service endpoints setup: 


>>>    1. ‘oidcsim’ which I switched to swagger v3 annotations
>>>    2. ‘openapi’ currently still swagger v2 annotations
>>>    3. ‘sdx’ currently still swagger v2 annotations 






>>> all endpoints work except for the ‘swagger endpoint address for the
>>> oidcsim
>>> endpoint:
>>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services/o
>>> i
>>> dcsim/swagger.json 


>>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*
>>> endpoint of the oidcsim resource. I am getting an error (the value of
>>> the ‘url’ query parameter isn’t relevant): 






>>>         “WebApplicationException has been caught, status: 404,
>>> message: HTTP 404 Not Found” 






>>> When I try (without the ‘/oidcsim’ context):
>>> http://l-p53-008:8081/op/services/api-docs I get: 


>>>                “No service was found.” 






>>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs
>>> doesn’t exist, where as the endpoint
>>> http://l-p53-008:8081/op/services/api-docs does exist but no service
JPU>> description is found? 


>>> Of course my intention is to get working, as previously with the
>>> swagger v2 setup for which I then specifically added the
>>> *Swagger2Feature* config
>>> parameters: 


>>>                               <property name="basePath"
>>> value="/op/services/oidcsim"/> 


>>>                               <property name="usePathBasedConfig" 






>>> But I don’t find the according configuration options for the
>>> *OpenApiFeature* class or whether I should configure this in another way. 






>>> Any suggestions on this? 






>>> Regards, 






>>> J.P. 










>>> -----Original Message-----
>>> From: Andriy Redko <dr...@gmail.com>
>>> Sent: donderdag 25 mei 2023 2:27
>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>>> dev@cxf.apache.org
>>> Subject: Re: How to setup multiple JAXRS server endpoints 






>>> Hi Jean, 






>>> You may run into Swagger JAX-RS scanner limitations, as far as I can
>>> tell - it checks class annotations for SwaggerDefinition, does not
>>> traverse the hierarchy [1]. 






>>> [1]
>>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-
>>> j
>>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194 






>>> Best Regards, 


>>>     Andriy Redko 






>>>>  RE: How to setup multiple JAXRS server endpoints 






>>>> Still one question ); 






>>>> The generated swagger file doesn’t take into account the 


>>>> @SwaggerDefintion on my interface classes? 






>>>> As a test I looked at 


>>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma 


>>>> in/release/samples/jax_rs/description_swagger2_web** 


>>>> and** modified** sample2* 


>>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma 


>>>> in/release/samples/jax_rs/description_swagger2_web 


>>>> and modified sample2> as follows: 






>>>>    @Path("/sample2") 






>>>>       @Api(value = "/sample2",authorizations= 


>>>>       {@Authorization(value="bearer")},description = "Sample2
>>> (modified) JAX-RS 


>>>>       service with Swagger documentation") 






>>>>       @SwaggerDefinition( 






>>>>               info = @Info( 






>>>>                       description = "Sample2 server", 






>>>>                       version="1.0", 






>>>>                       title = "Test2", 






>>>>                       contact = @Contact(name = "J.P. Urkens",email = " 


>>>>       *jean-pierre.urkens@devoteam.com* <
>>> jean-pierre.urkens@devoteam.com> 


>>>>       ")), 






>>>>               securityDefinition = 


>>>>       @SecurityDefinition(apiKeyAuthDefinitions= 


>>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="A
>>> u
>>> thorization",description="Use* 


>>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer 


>>>>       &lt;accessToken&gt;'")}) 






>>>>       ) 






>>>>       public class Sample2 {...} 






>>>> This correctly generates the ‘securityDefintions’ in the swagger file. 






>>>> If include the same @SwaggerDefinition and the authorizations on 


>>>> the @Api annotation as above in my interface classes then the 


>>>> generated swagger file doesn’t contain the ‘securityDefintions’ ? 






>>>> Any idea what I might be missing? 






>>>> Regards, 






>>>> J.P. 






>>>> -----Original Message----- 


>>>> From: Jean Pierre URKENS <je...@devoteam.com> 


>>>> Sent: dinsdag 23 mei 2023 12:52 


>>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' < 




>>>> Subject: RE: How to setup multiple JAXRS server endpoints 






>>>> Hi Andriy, 






>>>> I added the parameter usePathBasedConfig=true to the 


>>>> Swagger2Feature bean declarations but still it does generate an 


>>>> empty swagger.yaml for interfaces KmopResources and 


>>>> KmopDienstverlener although I noticed that for these interfaces the 


>>>> @Path() annotation was commented out (as I included it in the 


>>>> server declaration). After providing an empty @Path("") declaration
>>>> on
>>> the API interface classes everything worked. 






>>>> Thanks for the support. 






>>>> -----Original Message----- 






>>>> From: Andriy Redko <dr...@gmail.com> 






>>>> Sent: dinsdag 23 mei 2023 3:42 






>>>> To: Jean Pierre URKENS <je...@devoteam.com>; 


>>>> dev@cxf.apache.org 






>>>> Subject: Re: How to setup multiple JAXRS server endpoints 






>>>> Hi Jean, 






>>>> The main problem to configure Swagger property in your particular 


>>>> case is that the server address is not "known" or "introspectable"
>>>> for
>>> Swagger. 


>>>> Intuitively, it has to be set manually using basePath to the, 


>>>> essentially, the server address 






>>>> part: 






>>>>  - /op/services/accounts 






>>>>  - /op/services/resources 






>>>>  - /op/services/dienstverlener 






>>>> You could read more about other Swagger properties you have asked here: 


>>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte 


>>>> gration-and-Configuration#configuration-properties 






>>>> You definitely need to set usePathBasedConfig to "true" otherwise 


>>>> you will see the same Swagger specs for all servers. We have a 


>>>> sample here which uses 2 jaxrs:server 






>>>> instances: 


>>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai 


>>>> n/release/samples/jax_rs/description_swagger2_web 






>>>> Regarding SwaggerUI, I think the value for each of those should be 


>>>> set to, 


>>>> respectively: 






>>>>  - /op/services/accounts/swagger.yaml 






>>>>  - /op/services/resources/swagger.yaml 






>>>>  - /op/services/dienstverlener/swagger.yaml 






>>>> I believe this is matching your settings already, except the 


>>>> usePathBasedConfig part. The example referred above could be 


>>>> helpful, my apologies if I missed something, there are quite a lot 


>>>> of questions :-) The fact that the generated Swagger specification 


>>>> is empty is unexpected - it should not happen when JAX-RS resources
>>> are properly configured. 






>>>> Thank you. 






>>>> Best Regards, 






>>>>     Andriy Redko 






>>>>>  RE: How to setup multiple JAXRS server endpoints 






>>>>> Hi Andriy, 






>>>>> I am not quite understanding how to correctly configure the 


>>>> Swagger2Feature. 






>>>>> Referring to the attached cxf-endpoints configuration I (as a 


>>>>> test) 






>>>>> created 






>>>>> 3 JAXRS server instances: 






>>>>> 1.      A* KmopApiServer* server for the* 






>>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving 






>>>>> requests for URI path: 






>>>>>        * <protocol>**//<host:<port>/op/services/accounts* 






>>>>>    ‘op’  = root path of the web application 






>>>>>             ‘services’ = servlet path of the CXF-servlet 






>>>>>       The address of the server is set to ‘/accounts’ and the 


>>>>> @Path(…) 






>>>>>       annotation on the interface class was cleared. 






>>>>> 2.      A* Kmop**Resources**ApiServer* server for the*
>>> be.dvtm.aeo.op.* 






>>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving 






>>>>> requests for URI path: 






>>>>>        * <protocol>**//<host:<port>/op/services/**resources* 






>>>>> The address of the server is set to ‘/resources’ and the @Path(…) 






>>>>> annotation on the interface class was cleared. 






>>>>> 3.      A* Kmop**Dienstverlener**Server* server for the* 


>>>> be.dvtm.aeo.op.* 






>>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving 






>>>>> requests for URI path: 






>>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener* 






>>>>> The address of the server is set to ‘/dienstverlener’ and the 






>>>>> @Path(…) annotation on the interface class was cleared. 






>>>>> For each of these server instances I’ve set the Swagger2Feature 






>>>>> with configuration as indicated in the attached cxf-endpoints.xml. 






>>>>> With regard to the configurations for the Swagger2Feature I’ve the 






>>>>> following questions: 






>>>>> a)      Referring to *
>>> https://cxf.apache.org/docs/swagger2feature.html* 






>>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you 






>>>>> clarify on the following configuration parameters: 






>>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘ 






>>>>> /op/services’) or to the JAX-RS server instance (e.g. 






>>>>> ‘/op/services/accounts’) or still something else? Is it used to 






>>>>> resolve service classes or is it just for documentation in the 


>>>>> swagger 


>>>> file? 






>>>>> *ii.    ** resourcePackage* – the description mentions ‘package names’ 






>>>>> while the default mentions ‘service classes’? Service 2 and 3 


>>>>> above 






>>>>> are within the same package (generated from the same yaml 






>>>>> specification that included both interfaces). 






>>>>> *iii.   ** ig**noreRoutes* – is this taken into account when 






>>>>> scanAllResources=false? 






>>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter
>>> value 






>>>>> (cf. question ‘a’)? 






>>>>> b)      What would be the correct URL to generate a swagger.yaml
>>>>> file 


>>>> for 






>>>>> each of the above interfaces? Initially I called: 






>>>>> *i.     ** 


>>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml* 






>>>>> *ii.    ** 


>>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml* 






>>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver* 






>>>>> *lener/swagger.yaml* 






>>>>>    All three requests delivered the same yaml specification, 


>>>>> namely 


>>>> the one 






>>>>>       for interface* KmopApiServer*? 






>>>>> c)      I tried to debug the processing of the requests under ‘b)’
>>>>> and 


>>>> this 






>>>>> is done by the class JAXRSInterceptor#processRequest where the 






>>>>> MessageImpl object for request “ii.” looks like the one attached. 






>>>>> It finds 3 resource 






>>>>> classes: 






>>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl 






>>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource 






>>>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService 






>>>>> è       It matches the request to resource* 


>>>> Swagger2ApiListingResource* with 






>>>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its* 






>>>>> process(…)* method. 






>>>>> è       Here it seems to go wrong. It generates a
>>> SwaggerContextService 






>>>>> having basePath=/op/services/resources/,swaggerConfig=null, 






>>>>> usePathBasedConfig=null and then calls 






>>>>> SwaggerContextService.getSwagger() 






>>>>> which returns the Swagger definition for interface KmopApiServer? 






>>>>> It looks like it caches generated swagger definitions based on a 






>>>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the 






>>>>> same for all 3 interfaces as usePathBasedConfig=null 






>>>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is 






>>>>> derived from the ServletConfig parameter 






>>>>> ‘swagger.use.path.based.config’.* So should this be set on the 






>>>>> declaration of the CXFServlet** in web.xml?* 






>>>>> è       Actually the SwaggerConfig, the JaxrsScanner and the
>>>>> generated 


>>>> Swagger 






>>>>> are cached using keys like 






>>>>> ‘swagger.config.id.[default|baseUriPath]’, ‘ 






>>>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’ 


>>>> is only done when usePathBasedconfig=true. 






>>>>> è       If I patch this to true then configIdKey=’ 






>>>>> swagger.config.id./op/services/resources/’ and no swagger entry is 






>>>>> cached for this key so it will generate a new one. Again by 






>>>>> patching 






>>>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru 


>>>>> e 






>>>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);” 






>>>>> è       Again Scanners are cached and if usePathBasedConfig=null it 


>>>> will use 






>>>>> the one cached under  ‘swagger.scanner.id.default’ and this again 






>>>>> returns the swagger definition for the KmopApiService interface. 






>>>>> è       So patching usePathBasedConfig=true will return a new one 






>>>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner 






>>>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘ 






>>>>> which is correct. It will generate a new (but empty) Swagger object. 






>>>>> è       Next Swagger2ApiListingResource will call the 






>>>>> customizer.customize(s), which still isn’t putting anything new in 






>>>>> the Swagger object. Should it or should the next step do this? 






>>>>> è       Next BaseApiListingResource#getListing(…) is called which on 


>>>> its 






>>>>> turn calls getListingYamlResponse(..) 






>>>>> è       The final result is a swagger.yaml document with following 


>>>> content: 






>>>>>    swagger: "2.0" 






>>>>>       info: 






>>>>>         license: 






>>>>>           name: "Apache 2.0 License" 






>>>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html 






>>>>>       basePath: "/op/services/resources" 






>>>>>        So basically an empty swagger file. 






>>>>> d)      The usePathBasedConfig is derived from the ServletConfig 


>>>> parameter ‘ 






>>>>> swagger.use.path.based.config’. Without this parameter set to true 






>>>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger 






>>>>> object.* So should this be set on the declaration of the 






>>>>> CXFServlet** in web.xml?* 






>>>>> The majority in this processing happens in the library 






>>>>> swagger-jaxrs-v1.6.10 which is included as a dependency on 


>>>> cxf-rt-rs-service-description-swagger. 






>>>>> Even if I patch usePathBasedConfig=true about everywhere where I 






>>>>> met this it still doesn’t generate a correct swagger.yaml. Am I 






>>>>> still missing some configuration parameter? 






>>>>> Any suggestions on how to resolve this would be welcome. 






>>>>> Regards, 






>>>>> J.P. Urkens 










































>>>>> <<...>> <<...>> 






>>>>> -----Original Message----- 






>>>>> From: Andriy Redko <dr...@gmail.com> 






>>>>> Sent: maandag 8 mei 2023 23:15 






>>>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev 






>>>>> List < 












>>>>> Subject: Re: How to setup multiple JAXRS server endpoints 






>>>>> Hi Jean, 






>>>>> Indeed the way you would like to do that is somewhat tricky. 






>>>>>> So I tried to keep the @Path declaration on the interface classes 


>>>>>> but 






>>>>> changed them to @Path(“”). That does seems to work except the 






>>>>> swagger stuff no longer correctly works. 






>>>>> This is one of the possible options but OpenAPI/Swagger gets 






>>>>> confused for a 






>>>>> reason: the path is now implicit (not in the spec). 






>>>>> So how about this option: 






>>>>>  - use only one JAX-RS server (address "/") 






>>>>>  - host both resources but use @Path("accounts") and 






>>>>> @Path("resources") on them respectively 










>>>>> I see that for @Path("accounts") you need to apply the 






>>>>> "kmopApiAuthorizationFilter", that could be done using 






>>>>> DynamicFeature [1], [2]. If this is not the option and you would 






>>>>> prefer to use 2 separate JAX-RS servers, you may need to provide 






>>>>> your own instance of Swagger2Customizer [3], [4] which allows to 






>>>>> transform the OpenAPI/Swagger on the fly. Please let me know if 


>>>>> that 


>>>> would it work for you, thank you. 






>>>>> [1] 






>>>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic 


>>>>> F 






>>>>> eature.html 






>>>>> [2] 






>>>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born 


>>>>> - 






>>>>> equal.html 






>>>>> [3] 






>>>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger 


>>>>> / 






>>>>> Swagger2Customizer.html 






>>>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has 






>>>>> customizer 






>>>>> property) 










>>>>> Best Regards, 






>>>>>     Andriy Redko 






>>>>>> Hi Andriy, 






>>>>>> I am again getting into trouble with server endpoint declarations. 






>>>>>> Now 






>>>>> because I am adding additional JAX-RS endpoints. 






>>>>>> The issue is with: 






>>>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration
>>>>>> in 






>>>>> combination with 






>>>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the
>>>>>> web.xml 






>>>>> in combination with 






>>>>>> 3.      The @Path declaration in the interface class in combination
>>>>>> with 






>>>>>> 4.      The @Path declaration on the interface method in
>>>>>> combination
>>> with 






>>>>>> So what I had is that my web application deployed under baseUlr 'op' 






>>>>>> had 






>>>>> one JAXRS server endpoint with declarations like: 






>>>>>> 1.      <jaxrs:server id="restServer" 






>>>>> basePackages="be.dvtm.aeo.op.sodexo" address="/"> 






>>>>>> 2.      <url-pattern>/services/*</url-pattern> 






>>>>>> 3.      @Path("accounts") on the public interface class 






>>>>>> 4.      @Path("/{authorisationId}/customerFund") on the
>>>>>> customerFund 






>>>>> interface method 






>>>>>> A valid API call would thus be e.g.: 






>>>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/c
>>>>>> u
>>>>>> s 


>>>>>> t 






>>>>>> o 






>>>>>> merFund 






>>>>>> And this works correctly. 






>>>>>> We're now introducing additional JAX-RS service endpoints and now
>>>>>> I 






>>>>>> am 






>>>>> running into problems. This second endpoint was declared with: 






>>>>>> 1.      <jaxrs:server id="resourceServer" 






>>>>> basePackages="be.dvtm.aeo.op.resources" address="/"> 






>>>>>> 2.      <url-pattern>/services/*</url-pattern> 






>>>>>> 3.      @Path("resources") on the public interface class 






>>>>>> 4.      @Path("/NACE") on the NACE interface method 






>>>>>> So here a valid API call woud be: 






>>>>> https://<hostname>:<port>/op/services/resources/NACE. 






>>>>>> The problem is that I can not declare two <jaxrs:server> entries 


>>>>>> with 






>>>>>> the 






>>>>> same ‘address’ as it throws the exception: 






>>>>>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException: 






>>>>> There is an endpoint already running on /. 






>>>>>>  So I tried changing the addresses to: 






>>>>>> ·       address=”accounts” for the restServer 






>>>>>> ·       address=”resources” for the resourceServer 






>>>>>> But to keep the API-call URLs the same I removed the @Path 






>>>>>> declaration on 






>>>>> the interface classes. By doing so the <jaxrs:server> bean 






>>>>> declarations no longer loads successfully. 






>>>>>> So I tried to keep the @Path declaration on the interface classes 


>>>>>> but 






>>>>> changed them to @Path(“”). That does seems to work except the 






>>>>> swagger stuff no longer correctly works. 






>>>>>> So what is the decent way to setup multiple JAX-RS server
>>>>>> endpoints 






>>>>>> where 






>>>>> each server has its own configuration regarding supported features: 






>>>>>> ·       own validation 






>>>>>> ·       own object and exception mappings 






>>>>>> ·       own swagger file generation 






>>>>>> ·       own logging (in separate file if possible) 






>>>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in 






>>>>>> cooperation 






>>>>> with swager-ui v4.5.0. 






>>>>>> Below the declarations of my endpoints <<...>> Thanks for any advice. 






>>>>>> Regards, 






>>>>>> J.P. Urkens 






>>>>>> -----Original Message----- 






>>>>>> From: Andriy Redko <dr...@gmail.com> 






>>>>>> Sent: zaterdag 18 juni 2022 1:12 






>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>; 






>>>>>> issues@cxf.apache.org; dev@cxf.apache.org 






>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi
>>>>>> Jean, 






>>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1' 






>>>>>> Correct, so in the relative form like address="/<something>", the 






>>>>>> JAX-RS 






>>>>> endpoint path would be: 






>>>>>>     <baseUrl>/<servlet path 






mapping>>>>>>>/<address>/[@ApplicationPath]/[@Path] 






>>>>>> The @ApplicationPath is optional in this case. 






>>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2' 






>>>>>> The JAX-WS is very different from JAX-RS, essentially the action 






>>>>>> comes 






>>>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/ 






>>>>> (@Path / @ApplicationPath are not relevant there). 






>>>>>>> Question: Because now address="/" is set for the jaxrs:server
>>>>>>> will 






>>>>>>> it 






>>>>>>> also inspect requests targeted for the jaxws service as those 






>>>>>>> requests have start with the same path '/<basePath>/services/... 






>>>>>> This is a good question, I have not done it myself but I think it 






>>>>>> should 






>>>>> work: 






>>>>>> the servlet dispatches according to registered services, in this 






>>>>>> regard 






>>>>> JAX-RS and JAX-WS should not conflict. Does it work in your case? 


>>>> Thank you. 






>>>>>> Best Regards, 






>>>>>>     Andriy Redko 






>>>>>>> Hi Andriy, 






>>>>>>> Using address="/" seems to work but still I don't understand how 


>>>>>>> the 






>>>>>>> following work together: 






>>>>>>>  - path specification in servlet mapping for the CXF servlet 






>>>>>>> (org.apache.cxf.transport.servlet.CXFServlet) 






>>>>>>>  - the 'address' attribute on the jaxrs:server bean declaration 






>>>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the 






>>>>>>> service API description Say I've two services with (relateive to 


>>>>>>> the 






>>>>>>> host) url's: 






>>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1' 






>>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2' 






>>>>>>> How do I configure above 3 aspects? Currently I have (working): 






>>>>>>> 1.for the jaxrs:server endpoint: 






>>>>>>>         - servlet path mapping: '/services/*' 






>>>>>>>                - jaxrs-server address attribute: address="/" 






>>>>>>>                - @Path annotation: @Path("service1") 2.For the 


>>>>>>> jaxws 






>>>>>>> service endpoint: 






>>>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS 






>>>>>>> requests are handleb by the same CXF servle) 






>>>>>>>                - jaxws:endpoint server address attribute: 






>>>>>>> address="/service2" 






>>>>>>>                - @WebService(name="service2") A correct request
>>>>>>> for 






>>>>>>> '1' would be '/basePath>/services/service1/<ID>'. 






>>>>>>> A correct request for '2' would be '/basePath>/services/service2'. 






>>>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect to: 






>>>>>>>         - the server address attribute 






>>>>>>>         - The API annotation (@Path or @Webservice) The JAXWS 


>>>>>>> server 






>>>>>>> address attribute doesn't seem to interfere with the @Webservice 






>>>>>>> annotation. While the jaxrs server address attribute does seem to 






>>>>>>> interfere with the @Path annotation. I would have expected the 


>>>>>>> jaxrs 






>>>>>>> server aspects to be configured as: 






>>>>>>>         - servlet path mapping: '/services/*' 






>>>>>>>                - jaxrs-server address attribute: address="/service1" 






>>>>>>>                - @Path annotation: @Path("service1") but then a 






>>>>>>> valid 






>>>>>>> request would be 






>>>>>>>> /services/service1/service1/<ID>'. 






>>>>>>> For both the 'address' attribute is relative to the servlet path. 






>>>>>>> The @Path Javadoc mentions that this path is relative to the 






>>>>>>> ApplicationPath which thus seems to be relative to the
>>>>>>> jaxrs-server 






>>>>>>> address attribute. As for @Webservice it doesnn't seem to be 






>>>>>>> url-path 






>>>>> related. 






>>>>>>> Question: Because now address="/" is set for the jaxrs:server
>>>>>>> will 






>>>>>>> it 






>>>>>>> also inspect requests targeted for the jaxws service as those 






>>>>>>> requests have start with the same path '/<basePath>/services/...'. 






>>>>>>> Albeit somewhat confusing. 






>>>>>>> J.P. 






>>>>>>> -----Original Message----- 






>>>>>>> From: Andriy Redko <dr...@gmail.com> 






>>>>>>> Sent: dinsdag 14 juni 2022 1:08 






>>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>; 






>>>>>>> issues@cxf.apache.org; dev@cxf.apache.org 






>>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi
>>>>>>> Jean, 






>>>>>>> Indeed, the jaxrs:server does not expect address to be omitted,
>>>>>>> you 






>>>>>>> could use the "/" (and I believe an empty string would also make it): 






>>>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ... 






>>>>>>> </jaxrs:server> 






>>>>>>> Thank you. 






>>>>>>> Hope it helps. 






>>>>>>> Best Regards, 






>>>>>>>     Andriy Redko 






>>>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean 






>>>>>>>> declarations 






>>>>>>>> like: 






>>>>>>>>      <jaxrs:server id="restServer" basePackages="xxx"> 






>>>>>>>>            <jaxrs:serviceBeans> 






>>>>>>>>                 <ref bean="TestApi" /> 






>>>>>>>>            </jaxrs:serviceBeans> 






>>>>>>>>            <jaxrs:providers> 






>>>>>>>>                 <…/> 






>>>>>>>>            </jaxrs:providers> 






>>>>>>>>            <jaxrs:features> 






>>>>>>>>                 <… /> 






>>>>>>>>            </jaxrs:features> 






>>>>>>>>            <jaxrs:inInterceptors> 






>>>>>>>>                 <… /> 






>>>>>>>>            </jaxrs:inInterceptors> 






>>>>>>>>            <jaxrs:outInterceptors>* 






>>>>>>>>                 <**…**/>* 






>>>>>>>>            </jaxrs:outInterceptors>* 






>>>>>>>>      </jaxrs:server> 










>>>>>>>> Here my “TestApi” bean interface is declared like: 






>>>>>>>>       @Path("accounts") 






>>>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*) 






>>>>>>>>        @Produces(MediaType.*APPLICATION_JSON*) 






>>>>>>>>        public interface TestApi { 






>>>>>>>>          … 






>>>>>>>>        } 






>>>>>>>> And CXF is triggered via a servlet configuration like: 






>>>>>>>>      <servlet> 






>>>>>>>>              <display-name>CXF Servlet</display-name> 






>>>>>>>>              <servlet-name>CXFServlet</servlet-name> 






>>>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</serv
>>>>>>>> l
>>>>>>>> e 






>>>>>>>> t 












>>>>>>>>        </servlet> 






>>>>>>>>        <servlet-mapping> 






>>>>>>>>              <servlet-name>CXFServlet</servlet-name> 






>>>>>>>>              <url-pattern>/services/*</url-pattern> 






>>>>>>>>        </servlet-mapping> 










>>>>>>>> Because I’ve got the @Path declaration on the interface type
>>>>>>>> I’ve 






>>>>>>>> omitted 






>>>>>>>> the address=”accounts” attribute on the jaxrs:server declaration 






>>>>>>>> since otherwise 






>>>>>>>> I noticed that the server would be listening to 






>>>>>>>> /basepath/services/ accounts/accounts/…). 






>>>>>>>> Now this configuration works perfectly, only when shutting down 






>>>>>>>> the application server cxf calls 






>>>>>>>>         ServerImpl#destroy() 






>>>>>>>> which delegates (via Obeservable) to 






>>>>>>>> AbstractHTTPDestination#deactivate() 






>>>>>>>> which calls 






>>>>>>>> registry.removeDestination(path). 






>>>>>>>> This path is null (no ‘address’ specified on jaxrs:server 






>>>>>>>> declaration) and results in a NPE on the registry Map. 






>>>>>>>> This causes an unclean shutdown of my server. 






>>>>>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly? 






>>>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration 






>>>>>>>> correctly interact with the @Path parameter on the API interface? 






>>>>> <<...>>


RE: How to setup multiple JAXRS server endpoints

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
 RE: How to setup multiple JAXRS server endpoints

Hi Andriy,

After having migrated everything to "io.swagger.v3.oas.annotations.*" the
swagger endpoints for each of my services became active.

So far so good, but I do notice that there are discrepancies when
annotating models, e.g.:

    public class Model1 {

        @Schema(description="The description I want for prop1")

         private Model2 prop1;

        @Schema(description="The description I want for prop2")

         private Model2 prop2;

        ...

      }

When I generate the openapi.[json|yaml] specification I see that both prop1
and prop2 have a reference to the schema component "Model2" with
description ' The description I want for prop2' which is inappropriate for
'prop1'.

It is not unlikely to have multiple properties within one Model that are of
the same class but are semantically used in a different context. E.g. something
as simple as a ShipmentOrder having two 'Address' properties 'from' and 'to'
would result in wrong API documentation.

I am aware it has nothing to do with CXF but rather with
swagger-jaxrs2-vx.y.z.jar
and depending libraries. CXF-3.5.6 has dependency on swagger-jaxrs2-2.1.13
.jar. Would it be an issue to replace this dependency with e.g.
swagger-jaxrs2-2.2.15.jar (latest stable release according to maven central
repo)?

J.P.

-----Original Message-----
From: Jean Pierre URKENS <je...@devoteam.com>
Sent: woensdag 12 juli 2023 8:25
To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <
dev@cxf.apache.org>
Subject: RE: How to setup multiple JAXRS server endpoints

I seem to be mistaken here, the endpoint was loaded (I did a manual HTTP
GET test to the endpoint to verify this) although no breakpoints where hit
during startup.

I am first going to complete the migration to
"io.swagger.v3.oas.annotations.*" annotations for all endpoints and then I
am going to test again.

The application is composed of libraries, some of which use SLF4J but most
use LOG4J for logging.

J.P.

-----Original Message-----

From: Andriy Redko <dr...@gmail.com>

Sent: woensdag 12 juli 2023 1:13

To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org

Subject: Re: How to setup multiple JAXRS server endpoints

Hi Jean,

The OpenApiFeature$Portable#initiliaze(…) should definitely be called
(otherwise you shouldn't even see the openapi.json endpoint), so I am not
sure why these are not triggering for you.



For logging, it seems like you are using SLF4J
(org.apache.cxf.common.logging.Slf4jLogger),

and also reload4j (aka log4j), why do you need both?

Thank you.

Best Regards,

    Andriy Redko

JPU> After some code investigation:


JPU> OpenApiFeature implements SwaggerUiSupport and in its

JPU> portable#registerSwaggerUiResources(…) method it will call

JPU> SwaggerUiSupport#getSwaggerUi(…) which will register the
SwaggerUiService.


JPU> I have put breakpoints on:

JPU>    - OpenApiFeature$Portable#initiliaze(…)

JPU>    - SwaggerUiService constructor

JPU>    - SwaggerUiSupport#getSwaggerUi(…)


JPU> but none of them are hit when starting my application?


JPU> Although the (spring) logging shows all beans in my

JPU> cxf-endpoints.xml have been created?

JPU> The *WADL* and *OpenAPI* endpoints to get the specification work.

JPU> Even the actual endpoint seems to work although I didn’t hit any of

JPU> the breakpoint?


JPU> CXF, also doesn’t seem to log a lot, I am hardly getting any log

JPU> entries although log level I set to DEBUG.

JPU> My logging (except wire message logging) for cxf is setup correctly

JPU> (I

JPU> think):

JPU>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line

JPU>    ‘org.apache.cxf.common.logging.Slf4jLogger’

JPU>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and

JPU>    reload4j-1.2.19.jar are on the classpath

JPU>    - the log4j.properties file contains the line:

JPU>    ‘log4j.logger.org.apache.cxf=DEBUG’


JPU> There are no special instructions mentioned on

JPU> https://cxf.apache.org/docs/general-cxf-logging.html so the above

JPU> should work (it works for all other packages I use in my application).


JPU> J.P.

JPU> *From:* Jean Pierre URKENS <je...@devoteam.com>

JPU> *Sent:* dinsdag 11 juli 2023 9:58

JPU> *To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <

dev@cxf.apache.org>>

JPU> *Subject:* RE: How to setup multiple JAXRS server endpoints


JPU> Hi Andriy,


JPU> As a test I removed all JAX-RS endpoints that use Swagger v2

JPU> annotations from my configuration file (see attachment).

JPU> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger v3

JPU> annotations, using the OpenApiFeature i.o. Swagger2Feature.

JPU> If I run my server with this configuration I only get the (working)

JPU> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint:




JPU> So there is some configuration missing to detect/activate the

JPU> Swagger endpoint. When I look at the samples that come with the

JPU> distribution of CXF (I am using v3.5.6) nothing special seems to be
configured to activate this?

JPU> Do you have any idea how the SwaggerUiService is picked up when
loading?


JPU> J.P.


JPU> -----Original Message-----

JPU> From: Andriy Redko <dr...@gmail.com>

JPU> Sent: dinsdag 11 juli 2023 3:44

JPU> To: Jean Pierre URKENS <je...@devoteam.com>;

JPU> dev@cxf.apache.org

JPU> Subject: Re: How to setup multiple JAXRS server endpoints


JPU> Hi Jean,


JPU> I guess you figured one issue, swagger.json -> openapi.json, but to

JPU> be honest we have never tested or envisioned the application that

JPU> would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same time, I

JPU> am afraid this is just not supported. You may get things back on

JPU> track when going with OpenAPI 3.0 for all services.


JPU> Thank you.


JPU> Best Regards,

JPU>     Andriy Redko




>> Hi Andriy,






>> I am trying to trace the difference in handling with another

>> application where I’ve got only one CXF service endpoint that uses

>> swagger v3 openapi annotations.


>> There I see that when handling the Swagger page request (

>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json) the

>> JAXRSInInterceptor is calling:






>> *JAXRSUtils.**getRootResources*(Message message)






>> It contains 4 entries:


>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint

>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService














>> On the application described below with the service ‘oidcsim’ when

>> calling the swagger page request

>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the

>> result of the getRootResources doesn’t contain the ClassResourceInfo

>> ‘

>> SwaggerUiService’. It only contains 3 entries:


>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)

>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource






>> The SwaggerUiService is the one that is configured to handle the

JPU> ‘api-docs’

>> path-request. Since it is missing the request is tried to match with

>> the other two resources but fails, hence ‘NOT FOUND’ exception.






>> I can’t trace back where these rootResources are set and why the

>> SwaggerUiService’ isn’t listed.






>> J.P.


>> *From:* Jean Pierre URKENS <je...@devoteam.com>

>> *Sent:* maandag 10 juli 2023 13:43

>> *To:* 'Andriy Redko' <dr...@gmail.com>

>> *Subject:* RE: How to setup multiple JAXRS server endpoints






>> Andriy,






>> I am trying to switch from Swagger v2 to OpenApi v3 annotations

>> basically because my starting point is an OpenApi v3.0.7 yaml file

>> description and OpenAPI seems to be the way forward.


>> For applications where I have only one CXF JAX-RS endpoint exposed I

>> had no problems converting. However as soon as there are multiple

>> endpoints I run into troubles.






>> So, to recall, I've an application exposing 3 JAX-RS endpoints that

>> where previously annotated with swagger v2 annotations (i.e. package

>> io.swagger.annotations.*) which I migrated to


>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*). In

>> accordance I altered my CXF JAX-RS endpoint configuration from (only

>> showing relevant parts, see attachment for full setup):






>>                <!-- CXF Swagger2Feature -->


>>                <bean id="SwaggerUiConfigOidcApi"

>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">


>>                               <property name="queryConfigEnabled"


>>                               <property name="url"

>> value="/op/services/oidcsim/swagger.yaml"/>


>>                </bean>


>>                <bean id="Swagger2FeatureOidcApi"

>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">


>>                               <property name="basePath"

>> value="/op/services/oidcsim"/>


>>                               <property name="usePathBasedConfig"


>>                               <property name="resourcePackage"

>> value="be.dvtm.aeo.op.oidc"/>


>>                               <property name="supportSwaggerUi"


>>                               <property name="swaggerUiConfig"

>> ref="SwaggerUiConfigOidcApi"/>


>>                </bean>


>>                <jaxrs:server id="OidcProviderApiServer"

>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">


>>                               ....


>>                               <jaxrs:features>


>>                                              <ref

>> bean="Swagger2FeatureOidcApi" />


>>                               </jaxrs:features>


>>                               ...


>>                </jaxrs:server>






>> TO:


>>                <!-- CXF OpenAPIFeature -->


>>                <bean id="OidcSwaggerUiConfig"

>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">


>>                               <property name="queryConfigEnabled"


>>                               <property name="url"

>> value="openapi.json"/>


>>                </bean>


>>                <bean id="OidcOpenApiFeature"

>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">


>>                               <property name="supportSwaggerUi"


>>                               <property name="swaggerUiConfig"

>> ref="OidcSwaggerUiConfig"/>


>>                               <property name="swaggerUiVersion"


>>                               <property name="scan" value="false"/>


>>                               <property name="useContextBasedConfig"


>>                               <property name="resourcePackages"

>> value="be.dvtm.aeo.op.oidc"/>


>>                </bean>


>>                <jaxrs:server id="OidcProviderApiServer"

>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">


>>                               ....


>>                               <jaxrs:features>


>>                                              <ref

JPU> bean="OidcOpenApiFeature"


>>                               </jaxrs:features>


>>                               ...


>>                </jaxrs:server>










>> Now when starting my application and navigating to the root part "

>> http://localhost:localPort/op/services" I get an overview of all my

>> endpoints:






>> Now there are 3 RESTful service endpoints setup:


>>    1. ‘oidcsim’ which I switched to swagger v3 annotations

>>    2. ‘openapi’ currently still swagger v2 annotations

>>    3. ‘sdx’ currently still swagger v2 annotations






>> all endpoints work except for the ‘swagger endpoint address for the

>> oidcsim

>> endpoint:

>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services/o

>> i

>> dcsim/swagger.json


>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*

>> endpoint of the oidcsim resource. I am getting an error (the value of

>> the ‘url’ query parameter isn’t relevant):






>>         “WebApplicationException has been caught, status: 404,

>> message: HTTP 404 Not Found”






>> When I try (without the ‘/oidcsim’ context):

>> http://l-p53-008:8081/op/services/api-docs I get:


>>                “No service was found.”






>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs

>> doesn’t exist, where as the endpoint

>> http://l-p53-008:8081/op/services/api-docs does exist but no service

JPU> description is found?


>> Of course my intention is to get working, as previously with the

>> swagger v2 setup for which I then specifically added the

>> *Swagger2Feature* config

>> parameters:


>>                               <property name="basePath"

>> value="/op/services/oidcsim"/>


>>                               <property name="usePathBasedConfig"






>> But I don’t find the according configuration options for the

>> *OpenApiFeature* class or whether I should configure this in another way.






>> Any suggestions on this?






>> Regards,






>> J.P.










>> -----Original Message-----

>> From: Andriy Redko <dr...@gmail.com>

>> Sent: donderdag 25 mei 2023 2:27

>> To: Jean Pierre URKENS <je...@devoteam.com>;

>> dev@cxf.apache.org

>> Subject: Re: How to setup multiple JAXRS server endpoints






>> Hi Jean,






>> You may run into Swagger JAX-RS scanner limitations, as far as I can

>> tell - it checks class annotations for SwaggerDefinition, does not

>> traverse the hierarchy [1].






>> [1]

>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-

>> j

>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194






>> Best Regards,


>>     Andriy Redko






>>>  RE: How to setup multiple JAXRS server endpoints






>>> Still one question );






>>> The generated swagger file doesn’t take into account the


>>> @SwaggerDefintion on my interface classes?






>>> As a test I looked at


>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma


>>> in/release/samples/jax_rs/description_swagger2_web**


>>> and** modified** sample2*


>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma


>>> in/release/samples/jax_rs/description_swagger2_web


>>> and modified sample2> as follows:






>>>    @Path("/sample2")






>>>       @Api(value = "/sample2",authorizations=


>>>       {@Authorization(value="bearer")},description = "Sample2

>> (modified) JAX-RS


>>>       service with Swagger documentation")






>>>       @SwaggerDefinition(






>>>               info = @Info(






>>>                       description = "Sample2 server",






>>>                       version="1.0",






>>>                       title = "Test2",






>>>                       contact = @Contact(name = "J.P. Urkens",email = "


>>>       *jean-pierre.urkens@devoteam.com* <

>> jean-pierre.urkens@devoteam.com>


>>>       ")),






>>>               securityDefinition =


>>>       @SecurityDefinition(apiKeyAuthDefinitions=


>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="A
<*{@ApiKeyAuthDefinition(key=>

>> u

>> thorization",description="Use*


>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer


>>>       &lt;accessToken&gt;'")})






>>>       )






>>>       public class Sample2 {...}






>>> This correctly generates the ‘securityDefintions’ in the swagger file.






>>> If include the same @SwaggerDefinition and the authorizations on


>>> the @Api annotation as above in my interface classes then the


>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?






>>> Any idea what I might be missing?






>>> Regards,






>>> J.P.






>>> -----Original Message-----


>>> From: Jean Pierre URKENS <je...@devoteam.com>


>>> Sent: dinsdag 23 mei 2023 12:52


>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <




>>> Subject: RE: How to setup multiple JAXRS server endpoints






>>> Hi Andriy,






>>> I added the parameter usePathBasedConfig=true to the


>>> Swagger2Feature bean declarations but still it does generate an


>>> empty swagger.yaml for interfaces KmopResources and


>>> KmopDienstverlener although I noticed that for these interfaces the


>>> @Path() annotation was commented out (as I included it in the


>>> server declaration). After providing an empty @Path("") declaration

>>> on

>> the API interface classes everything worked.






>>> Thanks for the support.






>>> -----Original Message-----






>>> From: Andriy Redko <dr...@gmail.com>






>>> Sent: dinsdag 23 mei 2023 3:42






>>> To: Jean Pierre URKENS <je...@devoteam.com>;


>>> dev@cxf.apache.org






>>> Subject: Re: How to setup multiple JAXRS server endpoints






>>> Hi Jean,






>>> The main problem to configure Swagger property in your particular


>>> case is that the server address is not "known" or "introspectable"

>>> for

>> Swagger.


>>> Intuitively, it has to be set manually using basePath to the,


>>> essentially, the server address






>>> part:






>>>  - /op/services/accounts






>>>  - /op/services/resources






>>>  - /op/services/dienstverlener






>>> You could read more about other Swagger properties you have asked here:


>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte


>>> gration-and-Configuration#configuration-properties






>>> You definitely need to set usePathBasedConfig to "true" otherwise


>>> you will see the same Swagger specs for all servers. We have a


>>> sample here which uses 2 jaxrs:server






>>> instances:


>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai


>>> n/release/samples/jax_rs/description_swagger2_web






>>> Regarding SwaggerUI, I think the value for each of those should be


>>> set to,


>>> respectively:






>>>  - /op/services/accounts/swagger.yaml






>>>  - /op/services/resources/swagger.yaml






>>>  - /op/services/dienstverlener/swagger.yaml






>>> I believe this is matching your settings already, except the


>>> usePathBasedConfig part. The example referred above could be


>>> helpful, my apologies if I missed something, there are quite a lot


>>> of questions :-) The fact that the generated Swagger specification


>>> is empty is unexpected - it should not happen when JAX-RS resources

>> are properly configured.






>>> Thank you.






>>> Best Regards,






>>>     Andriy Redko






>>>>  RE: How to setup multiple JAXRS server endpoints






>>>> Hi Andriy,






>>>> I am not quite understanding how to correctly configure the


>>> Swagger2Feature.






>>>> Referring to the attached cxf-endpoints configuration I (as a


>>>> test)






>>>> created






>>>> 3 JAXRS server instances:






>>>> 1.      A* KmopApiServer* server for the*






>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving






>>>> requests for URI path:






>>>>        * <protocol>**//<host:<port>/op/services/accounts*






>>>>    ‘op’  = root path of the web application






>>>>             ‘services’ = servlet path of the CXF-servlet






>>>>       The address of the server is set to ‘/accounts’ and the


>>>> @Path(…)






>>>>       annotation on the interface class was cleared.






>>>> 2.      A* Kmop**Resources**ApiServer* server for the*

>> be.dvtm.aeo.op.*






>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving






>>>> requests for URI path:






>>>>        * <protocol>**//<host:<port>/op/services/**resources*






>>>> The address of the server is set to ‘/resources’ and the @Path(…)






>>>> annotation on the interface class was cleared.






>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*


>>> be.dvtm.aeo.op.*






>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving






>>>> requests for URI path:






>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*






>>>> The address of the server is set to ‘/dienstverlener’ and the






>>>> @Path(…) annotation on the interface class was cleared.






>>>> For each of these server instances I’ve set the Swagger2Feature






>>>> with configuration as indicated in the attached cxf-endpoints.xml.






>>>> With regard to the configurations for the Swagger2Feature I’ve the






>>>> following questions:






>>>> a)      Referring to *

>> https://cxf.apache.org/docs/swagger2feature.html*






>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you






>>>> clarify on the following configuration parameters:






>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘






>>>> /op/services’) or to the JAX-RS server instance (e.g.






>>>> ‘/op/services/accounts’) or still something else? Is it used to






>>>> resolve service classes or is it just for documentation in the


>>>> swagger


>>> file?






>>>> *ii.    ** resourcePackage* – the description mentions ‘package names’






>>>> while the default mentions ‘service classes’? Service 2 and 3


>>>> above






>>>> are within the same package (generated from the same yaml






>>>> specification that included both interfaces).






>>>> *iii.   ** ig**noreRoutes* – is this taken into account when






>>>> scanAllResources=false?






>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter

>> value






>>>> (cf. question ‘a’)?






>>>> b)      What would be the correct URL to generate a swagger.yaml

>>>> file


>>> for






>>>> each of the above interfaces? Initially I called:






>>>> *i.     **


>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*






>>>> *ii.    **


>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*






>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*






>>>> *lener/swagger.yaml*






>>>>    All three requests delivered the same yaml specification,


>>>> namely


>>> the one






>>>>       for interface* KmopApiServer*?






>>>> c)      I tried to debug the processing of the requests under ‘b)’

>>>> and


>>> this






>>>> is done by the class JAXRSInterceptor#processRequest where the






>>>> MessageImpl object for request “ii.” looks like the one attached.






>>>> It finds 3 resource






>>>> classes:






>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl






>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource






>>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService






>>>> è       It matches the request to resource*


>>> Swagger2ApiListingResource* with






>>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*






>>>> process(…)* method.






>>>> è       Here it seems to go wrong. It generates a

>> SwaggerContextService






>>>> having basePath=/op/services/resources/,swaggerConfig=null,






>>>> usePathBasedConfig=null and then calls






>>>> SwaggerContextService.getSwagger()






>>>> which returns the Swagger definition for interface KmopApiServer?






>>>> It looks like it caches generated swagger definitions based on a






>>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the






>>>> same for all 3 interfaces as usePathBasedConfig=null






>>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is






>>>> derived from the ServletConfig parameter






>>>> ‘swagger.use.path.based.config’.* So should this be set on the






>>>> declaration of the CXFServlet** in web.xml?*






>>>> è       Actually the SwaggerConfig, the JaxrsScanner and the

>>>> generated


>>> Swagger






>>>> are cached using keys like






>>>> ‘swagger.config.id.[default|baseUriPath]’, ‘






>>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’


>>> is only done when usePathBasedconfig=true.






>>>> è       If I patch this to true then configIdKey=’






>>>> swagger.config.id./op/services/resources/’ and no swagger entry is






>>>> cached for this key so it will generate a new one. Again by






>>>> patching






>>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru


>>>> e






>>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”






>>>> è       Again Scanners are cached and if usePathBasedConfig=null it


>>> will use






>>>> the one cached under  ‘swagger.scanner.id.default’ and this again






>>>> returns the swagger definition for the KmopApiService interface.






>>>> è       So patching usePathBasedConfig=true will return a new one






>>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner






>>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘






>>>> which is correct. It will generate a new (but empty) Swagger object.






>>>> è       Next Swagger2ApiListingResource will call the






>>>> customizer.customize(s), which still isn’t putting anything new in






>>>> the Swagger object. Should it or should the next step do this?






>>>> è       Next BaseApiListingResource#getListing(…) is called which on


>>> its






>>>> turn calls getListingYamlResponse(..)






>>>> è       The final result is a swagger.yaml document with following


>>> content:






>>>>    swagger: "2.0"






>>>>       info:






>>>>         license:






>>>>           name: "Apache 2.0 License"






>>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html






>>>>       basePath: "/op/services/resources"






>>>>        So basically an empty swagger file.






>>>> d)      The usePathBasedConfig is derived from the ServletConfig


>>> parameter ‘






>>>> swagger.use.path.based.config’. Without this parameter set to true






>>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger






>>>> object.* So should this be set on the declaration of the






>>>> CXFServlet** in web.xml?*






>>>> The majority in this processing happens in the library






>>>> swagger-jaxrs-v1.6.10 which is included as a dependency on


>>> cxf-rt-rs-service-description-swagger.






>>>> Even if I patch usePathBasedConfig=true about everywhere where I






>>>> met this it still doesn’t generate a correct swagger.yaml. Am I






>>>> still missing some configuration parameter?






>>>> Any suggestions on how to resolve this would be welcome.






>>>> Regards,






>>>> J.P. Urkens










































>>>> <<...>> <<...>>






>>>> -----Original Message-----






>>>> From: Andriy Redko <dr...@gmail.com>






>>>> Sent: maandag 8 mei 2023 23:15






>>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev






>>>> List <












>>>> Subject: Re: How to setup multiple JAXRS server endpoints






>>>> Hi Jean,






>>>> Indeed the way you would like to do that is somewhat tricky.






>>>>> So I tried to keep the @Path declaration on the interface classes


>>>>> but






>>>> changed them to @Path(“”). That does seems to work except the






>>>> swagger stuff no longer correctly works.






>>>> This is one of the possible options but OpenAPI/Swagger gets






>>>> confused for a






>>>> reason: the path is now implicit (not in the spec).






>>>> So how about this option:






>>>>  - use only one JAX-RS server (address "/")






>>>>  - host both resources but use @Path("accounts") and






>>>> @Path("resources") on them respectively










>>>> I see that for @Path("accounts") you need to apply the






>>>> "kmopApiAuthorizationFilter", that could be done using






>>>> DynamicFeature [1], [2]. If this is not the option and you would






>>>> prefer to use 2 separate JAX-RS servers, you may need to provide






>>>> your own instance of Swagger2Customizer [3], [4] which allows to






>>>> transform the OpenAPI/Swagger on the fly. Please let me know if


>>>> that


>>> would it work for you, thank you.






>>>> [1]






>>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic


>>>> F






>>>> eature.html






>>>> [2]






>>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born


>>>> -






>>>> equal.html






>>>> [3]






>>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger


>>>> /






>>>> Swagger2Customizer.html






>>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has






>>>> customizer






>>>> property)










>>>> Best Regards,






>>>>     Andriy Redko






>>>>> Hi Andriy,






>>>>> I am again getting into trouble with server endpoint declarations.






>>>>> Now






>>>> because I am adding additional JAX-RS endpoints.






>>>>> The issue is with:






>>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration

>>>>> in






>>>> combination with






>>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the

>>>>> web.xml






>>>> in combination with






>>>>> 3.      The @Path declaration in the interface class in combination

>>>>> with






>>>>> 4.      The @Path declaration on the interface method in

>>>>> combination

>> with






>>>>> So what I had is that my web application deployed under baseUlr 'op'






>>>>> had






>>>> one JAXRS server endpoint with declarations like:






>>>>> 1.      <jaxrs:server id="restServer"






>>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">






>>>>> 2.      <url-pattern>/services/*</url-pattern>






>>>>> 3.      @Path("accounts") on the public interface class






>>>>> 4.      @Path("/{authorisationId}/customerFund") on the

>>>>> customerFund






>>>> interface method






>>>>> A valid API call would thus be e.g.:






>>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/c

>>>>> u

>>>>> s


>>>>> t






>>>>> o






>>>>> merFund






>>>>> And this works correctly.






>>>>> We're now introducing additional JAX-RS service endpoints and now

>>>>> I






>>>>> am






>>>> running into problems. This second endpoint was declared with:






>>>>> 1.      <jaxrs:server id="resourceServer"






>>>> basePackages="be.dvtm.aeo.op.resources" address="/">






>>>>> 2.      <url-pattern>/services/*</url-pattern>






>>>>> 3.      @Path("resources") on the public interface class






>>>>> 4.      @Path("/NACE") on the NACE interface method






>>>>> So here a valid API call woud be:






>>>> https://<hostname>:<port>/op/services/resources/NACE.






>>>>> The problem is that I can not declare two <jaxrs:server> entries


>>>>> with






>>>>> the






>>>> same ‘address’ as it throws the exception:






>>>>> Caused by:
org.apache.cxf.service.factory.ServiceConstructionException:






>>>> There is an endpoint already running on /.






>>>>>  So I tried changing the addresses to:






>>>>> ·       address=”accounts” for the restServer






>>>>> ·       address=”resources” for the resourceServer






>>>>> But to keep the API-call URLs the same I removed the @Path






>>>>> declaration on






>>>> the interface classes. By doing so the <jaxrs:server> bean






>>>> declarations no longer loads successfully.






>>>>> So I tried to keep the @Path declaration on the interface classes


>>>>> but






>>>> changed them to @Path(“”). That does seems to work except the






>>>> swagger stuff no longer correctly works.






>>>>> So what is the decent way to setup multiple JAX-RS server

>>>>> endpoints






>>>>> where






>>>> each server has its own configuration regarding supported features:






>>>>> ·       own validation






>>>>> ·       own object and exception mappings






>>>>> ·       own swagger file generation






>>>>> ·       own logging (in separate file if possible)






>>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in






>>>>> cooperation






>>>> with swager-ui v4.5.0.






>>>>> Below the declarations of my endpoints <<...>> Thanks for any advice.






>>>>> Regards,






>>>>> J.P. Urkens






>>>>> -----Original Message-----






>>>>> From: Andriy Redko <dr...@gmail.com>






>>>>> Sent: zaterdag 18 juni 2022 1:12






>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;






>>>>> issues@cxf.apache.org; dev@cxf.apache.org






>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi

>>>>> Jean,






>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'






>>>>> Correct, so in the relative form like address="/<something>", the






>>>>> JAX-RS






>>>> endpoint path would be:






>>>>>     <baseUrl>/<servlet path






mapping>>>>>>/<address>/[@ApplicationPath]/[@Path]






>>>>> The @ApplicationPath is optional in this case.






>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'






>>>>> The JAX-WS is very different from JAX-RS, essentially the action






>>>>> comes






>>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/






>>>> (@Path / @ApplicationPath are not relevant there).






>>>>>> Question: Because now address="/" is set for the jaxrs:server

>>>>>> will






>>>>>> it






>>>>>> also inspect requests targeted for the jaxws service as those






>>>>>> requests have start with the same path '/<basePath>/services/...






>>>>> This is a good question, I have not done it myself but I think it






>>>>> should






>>>> work:






>>>>> the servlet dispatches according to registered services, in this






>>>>> regard






>>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?


>>> Thank you.






>>>>> Best Regards,






>>>>>     Andriy Redko






>>>>>> Hi Andriy,






>>>>>> Using address="/" seems to work but still I don't understand how


>>>>>> the






>>>>>> following work together:






>>>>>>  - path specification in servlet mapping for the CXF servlet






>>>>>> (org.apache.cxf.transport.servlet.CXFServlet)






>>>>>>  - the 'address' attribute on the jaxrs:server bean declaration






>>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the






>>>>>> service API description Say I've two services with (relateive to


>>>>>> the






>>>>>> host) url's:






>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'






>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'






>>>>>> How do I configure above 3 aspects? Currently I have (working):






>>>>>> 1.for the jaxrs:server endpoint:






>>>>>>         - servlet path mapping: '/services/*'






>>>>>>                - jaxrs-server address attribute: address="/"






>>>>>>                - @Path annotation: @Path("service1") 2.For the


>>>>>> jaxws






>>>>>> service endpoint:






>>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS






>>>>>> requests are handleb by the same CXF servle)






>>>>>>                - jaxws:endpoint server address attribute:






>>>>>> address="/service2"






>>>>>>                - @WebService(name="service2") A correct request

>>>>>> for






>>>>>> '1' would be '/basePath>/services/service1/<ID>'.






>>>>>> A correct request for '2' would be '/basePath>/services/service2'.






>>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect
to:






>>>>>>         - the server address attribute






>>>>>>         - The API annotation (@Path or @Webservice) The JAXWS


>>>>>> server






>>>>>> address attribute doesn't seem to interfere with the @Webservice






>>>>>> annotation. While the jaxrs server address attribute does seem to






>>>>>> interfere with the @Path annotation. I would have expected the


>>>>>> jaxrs






>>>>>> server aspects to be configured as:






>>>>>>         - servlet path mapping: '/services/*'






>>>>>>                - jaxrs-server address attribute: address="/service1"






>>>>>>                - @Path annotation: @Path("service1") but then a






>>>>>> valid






>>>>>> request would be






>>>>>>> /services/service1/service1/<ID>'.






>>>>>> For both the 'address' attribute is relative to the servlet path.






>>>>>> The @Path Javadoc mentions that this path is relative to the






>>>>>> ApplicationPath which thus seems to be relative to the

>>>>>> jaxrs-server






>>>>>> address attribute. As for @Webservice it doesnn't seem to be






>>>>>> url-path






>>>> related.






>>>>>> Question: Because now address="/" is set for the jaxrs:server

>>>>>> will






>>>>>> it






>>>>>> also inspect requests targeted for the jaxws service as those






>>>>>> requests have start with the same path '/<basePath>/services/...'.






>>>>>> Albeit somewhat confusing.






>>>>>> J.P.






>>>>>> -----Original Message-----






>>>>>> From: Andriy Redko <dr...@gmail.com>






>>>>>> Sent: dinsdag 14 juni 2022 1:08






>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;






>>>>>> issues@cxf.apache.org; dev@cxf.apache.org






>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi

>>>>>> Jean,






>>>>>> Indeed, the jaxrs:server does not expect address to be omitted,

>>>>>> you






>>>>>> could use the "/" (and I believe an empty string would also make it):






>>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...






>>>>>> </jaxrs:server>






>>>>>> Thank you.






>>>>>> Hope it helps.






>>>>>> Best Regards,






>>>>>>     Andriy Redko






>>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean






>>>>>>> declarations






>>>>>>> like:






>>>>>>>      <jaxrs:server id="restServer" basePackages="xxx">






>>>>>>>            <jaxrs:serviceBeans>






>>>>>>>                 <ref bean="TestApi" />






>>>>>>>            </jaxrs:serviceBeans>






>>>>>>>            <jaxrs:providers>






>>>>>>>                 <…/>






>>>>>>>            </jaxrs:providers>






>>>>>>>            <jaxrs:features>






>>>>>>>                 <… />






>>>>>>>            </jaxrs:features>






>>>>>>>            <jaxrs:inInterceptors>






>>>>>>>                 <… />






>>>>>>>            </jaxrs:inInterceptors>






>>>>>>>            <jaxrs:outInterceptors>*






>>>>>>>                 <**…**/>*






>>>>>>>            </jaxrs:outInterceptors>*






>>>>>>>      </jaxrs:server>










>>>>>>> Here my “TestApi” bean interface is declared like:






>>>>>>>       @Path("accounts")






>>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)






>>>>>>>        @Produces(MediaType.*APPLICATION_JSON*)






>>>>>>>        public interface TestApi {






>>>>>>>          …






>>>>>>>        }






>>>>>>> And CXF is triggered via a servlet configuration like:






>>>>>>>      <servlet>






>>>>>>>              <display-name>CXF Servlet</display-name>






>>>>>>>              <servlet-name>CXFServlet</servlet-name>






>>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</serv

>>>>>>> l

>>>>>>> e






>>>>>>> t












>>>>>>>        </servlet>






>>>>>>>        <servlet-mapping>






>>>>>>>              <servlet-name>CXFServlet</servlet-name>






>>>>>>>              <url-pattern>/services/*</url-pattern>






>>>>>>>        </servlet-mapping>










>>>>>>> Because I’ve got the @Path declaration on the interface type

>>>>>>> I’ve






>>>>>>> omitted






>>>>>>> the address=”accounts” attribute on the jaxrs:server declaration






>>>>>>> since otherwise






>>>>>>> I noticed that the server would be listening to






>>>>>>> /basepath/services/ accounts/accounts/…).






>>>>>>> Now this configuration works perfectly, only when shutting down






>>>>>>> the application server cxf calls






>>>>>>>         ServerImpl#destroy()






>>>>>>> which delegates (via Obeservable) to






>>>>>>> AbstractHTTPDestination#deactivate()






>>>>>>> which calls






>>>>>>> registry.removeDestination(path).






>>>>>>> This path is null (no ‘address’ specified on jaxrs:server






>>>>>>> declaration) and results in a NPE on the registry Map.






>>>>>>> This causes an unclean shutdown of my server.






>>>>>>> Is this an error in cxf or is my jaxrs:server configured
incorrectly?






>>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration






>>>>>>> correctly interact with the @Path parameter on the API interface?






>>>> <<...>>

RE: How to setup multiple JAXRS server endpoints

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
I seem to be mistaken here, the endpoint was loaded (I did a manual HTTP GET
test to the endpoint to verify this) although no breakpoints where hit
during startup.
I am first going to complete the migration to
"io.swagger.v3.oas.annotations.*" annotations for all endpoints and then I
am going to test again.

The application is composed of libraries, some of which use SLF4J but most
use LOG4J for logging.

J.P.


-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: woensdag 12 juli 2023 1:13
To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
Subject: Re: How to setup multiple JAXRS server endpoints

Hi Jean,

The OpenApiFeature$Portable#initiliaze(…) should definitely be called
(otherwise you shouldn't even see the openapi.json endpoint), so I am not
sure why these are not triggering for you.

For logging, it seems like you are using SLF4J
(org.apache.cxf.common.logging.Slf4jLogger),
and also reload4j (aka log4j), why do you need both?

Thank you.

Best Regards,
    Andriy Redko

JPU> After some code investigation:



JPU> OpenApiFeature implements SwaggerUiSupport and in its
JPU> portable#registerSwaggerUiResources(…) method it will call
JPU> SwaggerUiSupport#getSwaggerUi(…) which will register the
SwaggerUiService.



JPU> I have put breakpoints on:

JPU>    - OpenApiFeature$Portable#initiliaze(…)
JPU>    - SwaggerUiService constructor
JPU>    - SwaggerUiSupport#getSwaggerUi(…)



JPU> but none of them are hit when starting my application?



JPU> Although the (spring) logging shows all beans in my
JPU> cxf-endpoints.xml have been created?

JPU> The *WADL* and *OpenAPI* endpoints to get the specification work.

JPU> Even the actual endpoint seems to work although I didn’t hit any of
JPU> the breakpoint?



JPU> CXF, also doesn’t seem to log a lot, I am hardly getting any log
JPU> entries although log level I set to DEBUG.

JPU> My logging (except wire message logging) for cxf is setup correctly
JPU> (I
JPU> think):

JPU>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line
JPU>    ‘org.apache.cxf.common.logging.Slf4jLogger’
JPU>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and
JPU>    reload4j-1.2.19.jar are on the classpath
JPU>    - the log4j.properties file contains the line:
JPU>    ‘log4j.logger.org.apache.cxf=DEBUG’



JPU> There are no special instructions mentioned on
JPU> https://cxf.apache.org/docs/general-cxf-logging.html so the above
JPU> should work (it works for all other packages I use in my application).



JPU> J.P.

JPU> *From:* Jean Pierre URKENS <je...@devoteam.com>
JPU> *Sent:* dinsdag 11 juli 2023 9:58
JPU> *To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <
dev@cxf.apache.org>>
JPU> *Subject:* RE: How to setup multiple JAXRS server endpoints



JPU> Hi Andriy,



JPU> As a test I removed all JAX-RS endpoints that use Swagger v2
JPU> annotations from my configuration file (see attachment).

JPU> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger v3
JPU> annotations, using the OpenApiFeature i.o. Swagger2Feature.

JPU> If I run my server with this configuration I only get the (working)
JPU> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint:





JPU> So there is some configuration missing to detect/activate the
JPU> Swagger endpoint. When I look at the samples that come with the
JPU> distribution of CXF (I am using v3.5.6) nothing special seems to be
configured to activate this?

JPU> Do you have any idea how the SwaggerUiService is picked up when
loading?



JPU> J.P.



JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: dinsdag 11 juli 2023 3:44
JPU> To: Jean Pierre URKENS <je...@devoteam.com>;
JPU> dev@cxf.apache.org
JPU> Subject: Re: How to setup multiple JAXRS server endpoints



JPU> Hi Jean,



JPU> I guess you figured one issue, swagger.json -> openapi.json, but to
JPU> be honest we have never tested or envisioned the application that
JPU> would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same time, I
JPU> am afraid this is just not supported. You may get things back on
JPU> track when going with OpenAPI 3.0 for all services.



JPU> Thank you.



JPU> Best Regards,

JPU>     Andriy Redko





>> Hi Andriy,







>> I am trying to trace the difference in handling with another

>> application where I’ve got only one CXF service endpoint that uses

>> swagger v3 openapi annotations.



>> There I see that when handling the Swagger page request (

>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json) the

>> JAXRSInInterceptor is calling:







>> *JAXRSUtils.**getRootResources*(Message message)







>> It contains 4 entries:



>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint

>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService















>> On the application described below with the service ‘oidcsim’ when

>> calling the swagger page request

>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the

>> result of the getRootResources doesn’t contain the ClassResourceInfo
>> ‘

>> SwaggerUiService’. It only contains 3 entries:



>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)

>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource







>> The SwaggerUiService is the one that is configured to handle the
JPU> ‘api-docs’

>> path-request. Since it is missing the request is tried to match with

>> the other two resources but fails, hence ‘NOT FOUND’ exception.







>> I can’t trace back where these rootResources are set and why the

>> SwaggerUiService’ isn’t listed.







>> J.P.



>> *From:* Jean Pierre URKENS <je...@devoteam.com>

>> *Sent:* maandag 10 juli 2023 13:43

>> *To:* 'Andriy Redko' <dr...@gmail.com>

>> *Subject:* RE: How to setup multiple JAXRS server endpoints







>> Andriy,







>> I am trying to switch from Swagger v2 to OpenApi v3 annotations

>> basically because my starting point is an OpenApi v3.0.7 yaml file

>> description and OpenAPI seems to be the way forward.



>> For applications where I have only one CXF JAX-RS endpoint exposed I

>> had no problems converting. However as soon as there are multiple

>> endpoints I run into troubles.







>> So, to recall, I've an application exposing 3 JAX-RS endpoints that

>> where previously annotated with swagger v2 annotations (i.e. package

>> io.swagger.annotations.*) which I migrated to



>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*). In

>> accordance I altered my CXF JAX-RS endpoint configuration from (only

>> showing relevant parts, see attachment for full setup):







>>                <!-- CXF Swagger2Feature -->



>>                <bean id="SwaggerUiConfigOidcApi"

>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>>                               <property name="queryConfigEnabled"



>>                               <property name="url"

>> value="/op/services/oidcsim/swagger.yaml"/>



>>                </bean>



>>                <bean id="Swagger2FeatureOidcApi"

>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">



>>                               <property name="basePath"

>> value="/op/services/oidcsim"/>



>>                               <property name="usePathBasedConfig"



>>                               <property name="resourcePackage"

>> value="be.dvtm.aeo.op.oidc"/>



>>                               <property name="supportSwaggerUi"



>>                               <property name="swaggerUiConfig"

>> ref="SwaggerUiConfigOidcApi"/>



>>                </bean>



>>                <jaxrs:server id="OidcProviderApiServer"

>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>>                               ....



>>                               <jaxrs:features>



>>                                              <ref

>> bean="Swagger2FeatureOidcApi" />



>>                               </jaxrs:features>



>>                               ...



>>                </jaxrs:server>







>> TO:



>>                <!-- CXF OpenAPIFeature -->



>>                <bean id="OidcSwaggerUiConfig"

>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>>                               <property name="queryConfigEnabled"



>>                               <property name="url"

>> value="openapi.json"/>



>>                </bean>



>>                <bean id="OidcOpenApiFeature"

>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">



>>                               <property name="supportSwaggerUi"



>>                               <property name="swaggerUiConfig"

>> ref="OidcSwaggerUiConfig"/>



>>                               <property name="swaggerUiVersion"



>>                               <property name="scan" value="false"/>



>>                               <property name="useContextBasedConfig"



>>                               <property name="resourcePackages"

>> value="be.dvtm.aeo.op.oidc"/>



>>                </bean>



>>                <jaxrs:server id="OidcProviderApiServer"

>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>>                               ....



>>                               <jaxrs:features>



>>                                              <ref
JPU> bean="OidcOpenApiFeature"



>>                               </jaxrs:features>



>>                               ...



>>                </jaxrs:server>











>> Now when starting my application and navigating to the root part "

>> http://localhost:localPort/op/services" I get an overview of all my

>> endpoints:







>> Now there are 3 RESTful service endpoints setup:



>>    1. ‘oidcsim’ which I switched to swagger v3 annotations

>>    2. ‘openapi’ currently still swagger v2 annotations

>>    3. ‘sdx’ currently still swagger v2 annotations







>> all endpoints work except for the ‘swagger endpoint address for the

>> oidcsim

>> endpoint:

>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services/o
>> i

>> dcsim/swagger.json



>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*

>> endpoint of the oidcsim resource. I am getting an error (the value of

>> the ‘url’ query parameter isn’t relevant):







>>         “WebApplicationException has been caught, status: 404,

>> message: HTTP 404 Not Found”







>> When I try (without the ‘/oidcsim’ context):

>> http://l-p53-008:8081/op/services/api-docs I get:



>>                “No service was found.”







>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs

>> doesn’t exist, where as the endpoint

>> http://l-p53-008:8081/op/services/api-docs does exist but no service
JPU> description is found?



>> Of course my intention is to get working, as previously with the

>> swagger v2 setup for which I then specifically added the

>> *Swagger2Feature* config

>> parameters:



>>                               <property name="basePath"

>> value="/op/services/oidcsim"/>



>>                               <property name="usePathBasedConfig"







>> But I don’t find the according configuration options for the

>> *OpenApiFeature* class or whether I should configure this in another way.







>> Any suggestions on this?







>> Regards,







>> J.P.











>> -----Original Message-----

>> From: Andriy Redko <dr...@gmail.com>

>> Sent: donderdag 25 mei 2023 2:27

>> To: Jean Pierre URKENS <je...@devoteam.com>;

>> dev@cxf.apache.org

>> Subject: Re: How to setup multiple JAXRS server endpoints







>> Hi Jean,







>> You may run into Swagger JAX-RS scanner limitations, as far as I can

>> tell - it checks class annotations for SwaggerDefinition, does not

>> traverse the hierarchy [1].







>> [1]

>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-
>> j

>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194







>> Best Regards,



>>     Andriy Redko







>>>  RE: How to setup multiple JAXRS server endpoints







>>> Still one question );







>>> The generated swagger file doesn’t take into account the



>>> @SwaggerDefintion on my interface classes?







>>> As a test I looked at



>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma



>>> in/release/samples/jax_rs/description_swagger2_web**



>>> and** modified** sample2*



>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma



>>> in/release/samples/jax_rs/description_swagger2_web



>>> and modified sample2> as follows:







>>>    @Path("/sample2")







>>>       @Api(value = "/sample2",authorizations=



>>>       {@Authorization(value="bearer")},description = "Sample2

>> (modified) JAX-RS



>>>       service with Swagger documentation")







>>>       @SwaggerDefinition(







>>>               info = @Info(







>>>                       description = "Sample2 server",







>>>                       version="1.0",







>>>                       title = "Test2",







>>>                       contact = @Contact(name = "J.P. Urkens",email = "



>>>       *jean-pierre.urkens@devoteam.com* <

>> jean-pierre.urkens@devoteam.com>



>>>       ")),







>>>               securityDefinition =



>>>       @SecurityDefinition(apiKeyAuthDefinitions=



>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="A
>> u

>> thorization",description="Use*



>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer



>>>       &lt;accessToken&gt;'")})







>>>       )







>>>       public class Sample2 {...}







>>> This correctly generates the ‘securityDefintions’ in the swagger file.







>>> If include the same @SwaggerDefinition and the authorizations on



>>> the @Api annotation as above in my interface classes then the



>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?







>>> Any idea what I might be missing?







>>> Regards,







>>> J.P.







>>> -----Original Message-----



>>> From: Jean Pierre URKENS <je...@devoteam.com>



>>> Sent: dinsdag 23 mei 2023 12:52



>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <





>>> Subject: RE: How to setup multiple JAXRS server endpoints







>>> Hi Andriy,







>>> I added the parameter usePathBasedConfig=true to the



>>> Swagger2Feature bean declarations but still it does generate an



>>> empty swagger.yaml for interfaces KmopResources and



>>> KmopDienstverlener although I noticed that for these interfaces the



>>> @Path() annotation was commented out (as I included it in the



>>> server declaration). After providing an empty @Path("") declaration

>>> on

>> the API interface classes everything worked.







>>> Thanks for the support.







>>> -----Original Message-----







>>> From: Andriy Redko <dr...@gmail.com>







>>> Sent: dinsdag 23 mei 2023 3:42







>>> To: Jean Pierre URKENS <je...@devoteam.com>;



>>> dev@cxf.apache.org







>>> Subject: Re: How to setup multiple JAXRS server endpoints







>>> Hi Jean,







>>> The main problem to configure Swagger property in your particular



>>> case is that the server address is not "known" or "introspectable"

>>> for

>> Swagger.



>>> Intuitively, it has to be set manually using basePath to the,



>>> essentially, the server address







>>> part:







>>>  - /op/services/accounts







>>>  - /op/services/resources







>>>  - /op/services/dienstverlener







>>> You could read more about other Swagger properties you have asked here:



>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte



>>> gration-and-Configuration#configuration-properties







>>> You definitely need to set usePathBasedConfig to "true" otherwise



>>> you will see the same Swagger specs for all servers. We have a



>>> sample here which uses 2 jaxrs:server







>>> instances:



>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai



>>> n/release/samples/jax_rs/description_swagger2_web







>>> Regarding SwaggerUI, I think the value for each of those should be



>>> set to,



>>> respectively:







>>>  - /op/services/accounts/swagger.yaml







>>>  - /op/services/resources/swagger.yaml







>>>  - /op/services/dienstverlener/swagger.yaml







>>> I believe this is matching your settings already, except the



>>> usePathBasedConfig part. The example referred above could be



>>> helpful, my apologies if I missed something, there are quite a lot



>>> of questions :-) The fact that the generated Swagger specification



>>> is empty is unexpected - it should not happen when JAX-RS resources

>> are properly configured.







>>> Thank you.







>>> Best Regards,







>>>     Andriy Redko







>>>>  RE: How to setup multiple JAXRS server endpoints







>>>> Hi Andriy,







>>>> I am not quite understanding how to correctly configure the



>>> Swagger2Feature.







>>>> Referring to the attached cxf-endpoints configuration I (as a



>>>> test)







>>>> created







>>>> 3 JAXRS server instances:







>>>> 1.      A* KmopApiServer* server for the*







>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving







>>>> requests for URI path:







>>>>        * <protocol>**//<host:<port>/op/services/accounts*







>>>>    ‘op’  = root path of the web application







>>>>             ‘services’ = servlet path of the CXF-servlet







>>>>       The address of the server is set to ‘/accounts’ and the



>>>> @Path(…)







>>>>       annotation on the interface class was cleared.







>>>> 2.      A* Kmop**Resources**ApiServer* server for the*

>> be.dvtm.aeo.op.*







>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving







>>>> requests for URI path:







>>>>        * <protocol>**//<host:<port>/op/services/**resources*







>>>> The address of the server is set to ‘/resources’ and the @Path(…)







>>>> annotation on the interface class was cleared.







>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*



>>> be.dvtm.aeo.op.*







>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving







>>>> requests for URI path:







>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*







>>>> The address of the server is set to ‘/dienstverlener’ and the







>>>> @Path(…) annotation on the interface class was cleared.







>>>> For each of these server instances I’ve set the Swagger2Feature







>>>> with configuration as indicated in the attached cxf-endpoints.xml.







>>>> With regard to the configurations for the Swagger2Feature I’ve the







>>>> following questions:







>>>> a)      Referring to *

>> https://cxf.apache.org/docs/swagger2feature.html*







>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you







>>>> clarify on the following configuration parameters:







>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘







>>>> /op/services’) or to the JAX-RS server instance (e.g.







>>>> ‘/op/services/accounts’) or still something else? Is it used to







>>>> resolve service classes or is it just for documentation in the



>>>> swagger



>>> file?







>>>> *ii.    ** resourcePackage* – the description mentions ‘package names’







>>>> while the default mentions ‘service classes’? Service 2 and 3



>>>> above







>>>> are within the same package (generated from the same yaml







>>>> specification that included both interfaces).







>>>> *iii.   ** ig**noreRoutes* – is this taken into account when







>>>> scanAllResources=false?







>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter

>> value







>>>> (cf. question ‘a’)?







>>>> b)      What would be the correct URL to generate a swagger.yaml

>>>> file



>>> for







>>>> each of the above interfaces? Initially I called:







>>>> *i.     **



>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*







>>>> *ii.    **



>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*







>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*







>>>> *lener/swagger.yaml*







>>>>    All three requests delivered the same yaml specification,



>>>> namely



>>> the one







>>>>       for interface* KmopApiServer*?







>>>> c)      I tried to debug the processing of the requests under ‘b)’

>>>> and



>>> this







>>>> is done by the class JAXRSInterceptor#processRequest where the







>>>> MessageImpl object for request “ii.” looks like the one attached.







>>>> It finds 3 resource







>>>> classes:







>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl







>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource







>>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService







>>>> è       It matches the request to resource*



>>> Swagger2ApiListingResource* with







>>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*







>>>> process(…)* method.







>>>> è       Here it seems to go wrong. It generates a

>> SwaggerContextService







>>>> having basePath=/op/services/resources/,swaggerConfig=null,







>>>> usePathBasedConfig=null and then calls







>>>> SwaggerContextService.getSwagger()







>>>> which returns the Swagger definition for interface KmopApiServer?







>>>> It looks like it caches generated swagger definitions based on a







>>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the







>>>> same for all 3 interfaces as usePathBasedConfig=null







>>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is







>>>> derived from the ServletConfig parameter







>>>> ‘swagger.use.path.based.config’.* So should this be set on the







>>>> declaration of the CXFServlet** in web.xml?*







>>>> è       Actually the SwaggerConfig, the JaxrsScanner and the

>>>> generated



>>> Swagger







>>>> are cached using keys like







>>>> ‘swagger.config.id.[default|baseUriPath]’, ‘







>>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’



>>> is only done when usePathBasedconfig=true.







>>>> è       If I patch this to true then configIdKey=’







>>>> swagger.config.id./op/services/resources/’ and no swagger entry is







>>>> cached for this key so it will generate a new one. Again by







>>>> patching







>>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru



>>>> e







>>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”







>>>> è       Again Scanners are cached and if usePathBasedConfig=null it



>>> will use







>>>> the one cached under  ‘swagger.scanner.id.default’ and this again







>>>> returns the swagger definition for the KmopApiService interface.







>>>> è       So patching usePathBasedConfig=true will return a new one







>>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner







>>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘







>>>> which is correct. It will generate a new (but empty) Swagger object.







>>>> è       Next Swagger2ApiListingResource will call the







>>>> customizer.customize(s), which still isn’t putting anything new in







>>>> the Swagger object. Should it or should the next step do this?







>>>> è       Next BaseApiListingResource#getListing(…) is called which on



>>> its







>>>> turn calls getListingYamlResponse(..)







>>>> è       The final result is a swagger.yaml document with following



>>> content:







>>>>    swagger: "2.0"







>>>>       info:







>>>>         license:







>>>>           name: "Apache 2.0 License"







>>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html







>>>>       basePath: "/op/services/resources"







>>>>        So basically an empty swagger file.







>>>> d)      The usePathBasedConfig is derived from the ServletConfig



>>> parameter ‘







>>>> swagger.use.path.based.config’. Without this parameter set to true







>>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger







>>>> object.* So should this be set on the declaration of the







>>>> CXFServlet** in web.xml?*







>>>> The majority in this processing happens in the library







>>>> swagger-jaxrs-v1.6.10 which is included as a dependency on



>>> cxf-rt-rs-service-description-swagger.







>>>> Even if I patch usePathBasedConfig=true about everywhere where I







>>>> met this it still doesn’t generate a correct swagger.yaml. Am I







>>>> still missing some configuration parameter?







>>>> Any suggestions on how to resolve this would be welcome.







>>>> Regards,







>>>> J.P. Urkens











































>>>> <<...>> <<...>>







>>>> -----Original Message-----







>>>> From: Andriy Redko <dr...@gmail.com>







>>>> Sent: maandag 8 mei 2023 23:15







>>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev







>>>> List <













>>>> Subject: Re: How to setup multiple JAXRS server endpoints







>>>> Hi Jean,







>>>> Indeed the way you would like to do that is somewhat tricky.







>>>>> So I tried to keep the @Path declaration on the interface classes



>>>>> but







>>>> changed them to @Path(“”). That does seems to work except the







>>>> swagger stuff no longer correctly works.







>>>> This is one of the possible options but OpenAPI/Swagger gets







>>>> confused for a







>>>> reason: the path is now implicit (not in the spec).







>>>> So how about this option:







>>>>  - use only one JAX-RS server (address "/")







>>>>  - host both resources but use @Path("accounts") and







>>>> @Path("resources") on them respectively











>>>> I see that for @Path("accounts") you need to apply the







>>>> "kmopApiAuthorizationFilter", that could be done using







>>>> DynamicFeature [1], [2]. If this is not the option and you would







>>>> prefer to use 2 separate JAX-RS servers, you may need to provide







>>>> your own instance of Swagger2Customizer [3], [4] which allows to







>>>> transform the OpenAPI/Swagger on the fly. Please let me know if



>>>> that



>>> would it work for you, thank you.







>>>> [1]







>>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic



>>>> F







>>>> eature.html







>>>> [2]







>>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born



>>>> -







>>>> equal.html







>>>> [3]







>>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger



>>>> /







>>>> Swagger2Customizer.html







>>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has







>>>> customizer







>>>> property)











>>>> Best Regards,







>>>>     Andriy Redko







>>>>> Hi Andriy,







>>>>> I am again getting into trouble with server endpoint declarations.







>>>>> Now







>>>> because I am adding additional JAX-RS endpoints.







>>>>> The issue is with:







>>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration

>>>>> in







>>>> combination with







>>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the

>>>>> web.xml







>>>> in combination with







>>>>> 3.      The @Path declaration in the interface class in combination

>>>>> with







>>>>> 4.      The @Path declaration on the interface method in

>>>>> combination

>> with







>>>>> So what I had is that my web application deployed under baseUlr 'op'







>>>>> had







>>>> one JAXRS server endpoint with declarations like:







>>>>> 1.      <jaxrs:server id="restServer"







>>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">







>>>>> 2.      <url-pattern>/services/*</url-pattern>







>>>>> 3.      @Path("accounts") on the public interface class







>>>>> 4.      @Path("/{authorisationId}/customerFund") on the

>>>>> customerFund







>>>> interface method







>>>>> A valid API call would thus be e.g.:







>>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/c
>>>>> u

>>>>> s



>>>>> t







>>>>> o







>>>>> merFund







>>>>> And this works correctly.







>>>>> We're now introducing additional JAX-RS service endpoints and now
>>>>> I







>>>>> am







>>>> running into problems. This second endpoint was declared with:







>>>>> 1.      <jaxrs:server id="resourceServer"







>>>> basePackages="be.dvtm.aeo.op.resources" address="/">







>>>>> 2.      <url-pattern>/services/*</url-pattern>







>>>>> 3.      @Path("resources") on the public interface class







>>>>> 4.      @Path("/NACE") on the NACE interface method







>>>>> So here a valid API call woud be:







>>>> https://<hostname>:<port>/op/services/resources/NACE.







>>>>> The problem is that I can not declare two <jaxrs:server> entries



>>>>> with







>>>>> the







>>>> same ‘address’ as it throws the exception:







>>>>> Caused by:
>>>>> org.apache.cxf.service.factory.ServiceConstructionException:







>>>> There is an endpoint already running on /.







>>>>>  So I tried changing the addresses to:







>>>>> ·       address=”accounts” for the restServer







>>>>> ·       address=”resources” for the resourceServer







>>>>> But to keep the API-call URLs the same I removed the @Path







>>>>> declaration on







>>>> the interface classes. By doing so the <jaxrs:server> bean







>>>> declarations no longer loads successfully.







>>>>> So I tried to keep the @Path declaration on the interface classes



>>>>> but







>>>> changed them to @Path(“”). That does seems to work except the







>>>> swagger stuff no longer correctly works.







>>>>> So what is the decent way to setup multiple JAX-RS server
>>>>> endpoints







>>>>> where







>>>> each server has its own configuration regarding supported features:







>>>>> ·       own validation







>>>>> ·       own object and exception mappings







>>>>> ·       own swagger file generation







>>>>> ·       own logging (in separate file if possible)







>>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in







>>>>> cooperation







>>>> with swager-ui v4.5.0.







>>>>> Below the declarations of my endpoints <<...>> Thanks for any advice.







>>>>> Regards,







>>>>> J.P. Urkens







>>>>> -----Original Message-----







>>>>> From: Andriy Redko <dr...@gmail.com>







>>>>> Sent: zaterdag 18 juni 2022 1:12







>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;







>>>>> issues@cxf.apache.org; dev@cxf.apache.org







>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi
>>>>> Jean,







>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'







>>>>> Correct, so in the relative form like address="/<something>", the







>>>>> JAX-RS







>>>> endpoint path would be:







>>>>>     <baseUrl>/<servlet path







mapping>>>>>>/<address>/[@ApplicationPath]/[@Path]







>>>>> The @ApplicationPath is optional in this case.







>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'







>>>>> The JAX-WS is very different from JAX-RS, essentially the action







>>>>> comes







>>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/







>>>> (@Path / @ApplicationPath are not relevant there).







>>>>>> Question: Because now address="/" is set for the jaxrs:server
>>>>>> will







>>>>>> it







>>>>>> also inspect requests targeted for the jaxws service as those







>>>>>> requests have start with the same path '/<basePath>/services/...







>>>>> This is a good question, I have not done it myself but I think it







>>>>> should







>>>> work:







>>>>> the servlet dispatches according to registered services, in this







>>>>> regard







>>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?



>>> Thank you.







>>>>> Best Regards,







>>>>>     Andriy Redko







>>>>>> Hi Andriy,







>>>>>> Using address="/" seems to work but still I don't understand how



>>>>>> the







>>>>>> following work together:







>>>>>>  - path specification in servlet mapping for the CXF servlet







>>>>>> (org.apache.cxf.transport.servlet.CXFServlet)







>>>>>>  - the 'address' attribute on the jaxrs:server bean declaration







>>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the







>>>>>> service API description Say I've two services with (relateive to



>>>>>> the







>>>>>> host) url's:







>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'







>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'







>>>>>> How do I configure above 3 aspects? Currently I have (working):







>>>>>> 1.for the jaxrs:server endpoint:







>>>>>>         - servlet path mapping: '/services/*'







>>>>>>                - jaxrs-server address attribute: address="/"







>>>>>>                - @Path annotation: @Path("service1") 2.For the



>>>>>> jaxws







>>>>>> service endpoint:







>>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS







>>>>>> requests are handleb by the same CXF servle)







>>>>>>                - jaxws:endpoint server address attribute:







>>>>>> address="/service2"







>>>>>>                - @WebService(name="service2") A correct request

>>>>>> for







>>>>>> '1' would be '/basePath>/services/service1/<ID>'.







>>>>>> A correct request for '2' would be '/basePath>/services/service2'.







>>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect
>>>>>> to:







>>>>>>         - the server address attribute







>>>>>>         - The API annotation (@Path or @Webservice) The JAXWS



>>>>>> server







>>>>>> address attribute doesn't seem to interfere with the @Webservice







>>>>>> annotation. While the jaxrs server address attribute does seem to







>>>>>> interfere with the @Path annotation. I would have expected the



>>>>>> jaxrs







>>>>>> server aspects to be configured as:







>>>>>>         - servlet path mapping: '/services/*'







>>>>>>                - jaxrs-server address attribute: address="/service1"







>>>>>>                - @Path annotation: @Path("service1") but then a







>>>>>> valid







>>>>>> request would be







>>>>>>> /services/service1/service1/<ID>'.







>>>>>> For both the 'address' attribute is relative to the servlet path.







>>>>>> The @Path Javadoc mentions that this path is relative to the







>>>>>> ApplicationPath which thus seems to be relative to the

>>>>>> jaxrs-server







>>>>>> address attribute. As for @Webservice it doesnn't seem to be







>>>>>> url-path







>>>> related.







>>>>>> Question: Because now address="/" is set for the jaxrs:server
>>>>>> will







>>>>>> it







>>>>>> also inspect requests targeted for the jaxws service as those







>>>>>> requests have start with the same path '/<basePath>/services/...'.







>>>>>> Albeit somewhat confusing.







>>>>>> J.P.







>>>>>> -----Original Message-----







>>>>>> From: Andriy Redko <dr...@gmail.com>







>>>>>> Sent: dinsdag 14 juni 2022 1:08







>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;







>>>>>> issues@cxf.apache.org; dev@cxf.apache.org







>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi

>>>>>> Jean,







>>>>>> Indeed, the jaxrs:server does not expect address to be omitted,

>>>>>> you







>>>>>> could use the "/" (and I believe an empty string would also make it):







>>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...







>>>>>> </jaxrs:server>







>>>>>> Thank you.







>>>>>> Hope it helps.







>>>>>> Best Regards,







>>>>>>     Andriy Redko







>>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean







>>>>>>> declarations







>>>>>>> like:







>>>>>>>      <jaxrs:server id="restServer" basePackages="xxx">







>>>>>>>            <jaxrs:serviceBeans>







>>>>>>>                 <ref bean="TestApi" />







>>>>>>>            </jaxrs:serviceBeans>







>>>>>>>            <jaxrs:providers>







>>>>>>>                 <…/>







>>>>>>>            </jaxrs:providers>







>>>>>>>            <jaxrs:features>







>>>>>>>                 <… />







>>>>>>>            </jaxrs:features>







>>>>>>>            <jaxrs:inInterceptors>







>>>>>>>                 <… />







>>>>>>>            </jaxrs:inInterceptors>







>>>>>>>            <jaxrs:outInterceptors>*







>>>>>>>                 <**…**/>*







>>>>>>>            </jaxrs:outInterceptors>*







>>>>>>>      </jaxrs:server>











>>>>>>> Here my “TestApi” bean interface is declared like:







>>>>>>>       @Path("accounts")







>>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)







>>>>>>>        @Produces(MediaType.*APPLICATION_JSON*)







>>>>>>>        public interface TestApi {







>>>>>>>          …







>>>>>>>        }







>>>>>>> And CXF is triggered via a servlet configuration like:







>>>>>>>      <servlet>







>>>>>>>              <display-name>CXF Servlet</display-name>







>>>>>>>              <servlet-name>CXFServlet</servlet-name>







>>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</serv
>>>>>>> l

>>>>>>> e







>>>>>>> t













>>>>>>>        </servlet>







>>>>>>>        <servlet-mapping>







>>>>>>>              <servlet-name>CXFServlet</servlet-name>







>>>>>>>              <url-pattern>/services/*</url-pattern>







>>>>>>>        </servlet-mapping>











>>>>>>> Because I’ve got the @Path declaration on the interface type
>>>>>>> I’ve







>>>>>>> omitted







>>>>>>> the address=”accounts” attribute on the jaxrs:server declaration







>>>>>>> since otherwise







>>>>>>> I noticed that the server would be listening to







>>>>>>> /basepath/services/ accounts/accounts/…).







>>>>>>> Now this configuration works perfectly, only when shutting down







>>>>>>> the application server cxf calls







>>>>>>>         ServerImpl#destroy()







>>>>>>> which delegates (via Obeservable) to







>>>>>>> AbstractHTTPDestination#deactivate()







>>>>>>> which calls







>>>>>>> registry.removeDestination(path).







>>>>>>> This path is null (no ‘address’ specified on jaxrs:server







>>>>>>> declaration) and results in a NPE on the registry Map.







>>>>>>> This causes an unclean shutdown of my server.







>>>>>>> Is this an error in cxf or is my jaxrs:server configured
>>>>>>> incorrectly?







>>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration







>>>>>>> correctly interact with the @Path parameter on the API interface?







>>>> <<...>>

Re: How to setup multiple JAXRS server endpoints

Posted by Andriy Redko <dr...@gmail.com>.
Hi Jean,

The OpenApiFeature$Portable#initiliaze(…) should definitely be 
called (otherwise you shouldn't even see the openapi.json endpoint), 
so I am not sure why these are not triggering for you.
        
For logging, it seems like you are using SLF4J (org.apache.cxf.common.logging.Slf4jLogger),
and also reload4j (aka log4j), why do you need both?

Thank you.

Best Regards,
    Andriy Redko

JPU> After some code investigation:



JPU> OpenApiFeature implements SwaggerUiSupport and in its
JPU> portable#registerSwaggerUiResources(…) method it will call
JPU> SwaggerUiSupport#getSwaggerUi(…) which will register the SwaggerUiService.



JPU> I have put breakpoints on:

JPU>    - OpenApiFeature$Portable#initiliaze(…)
JPU>    - SwaggerUiService constructor
JPU>    - SwaggerUiSupport#getSwaggerUi(…)



JPU> but none of them are hit when starting my application?



JPU> Although the (spring) logging shows all beans in my cxf-endpoints.xml have
JPU> been created?

JPU> The *WADL* and *OpenAPI* endpoints to get the specification work.

JPU> Even the actual endpoint seems to work although I didn’t hit any of the
JPU> breakpoint?



JPU> CXF, also doesn’t seem to log a lot, I am hardly getting any log entries
JPU> although log level I set to DEBUG.

JPU> My logging (except wire message logging) for cxf is setup correctly (I
JPU> think):

JPU>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line
JPU>    ‘org.apache.cxf.common.logging.Slf4jLogger’
JPU>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and
JPU>    reload4j-1.2.19.jar are on the classpath
JPU>    - the log4j.properties file contains the line:
JPU>    ‘log4j.logger.org.apache.cxf=DEBUG’



JPU> There are no special instructions mentioned on
JPU> https://cxf.apache.org/docs/general-cxf-logging.html so the above should
JPU> work (it works for all other packages I use in my application).



JPU> J.P.

JPU> *From:* Jean Pierre URKENS <je...@devoteam.com>
JPU> *Sent:* dinsdag 11 juli 2023 9:58
JPU> *To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <
dev@cxf.apache.org>>
JPU> *Subject:* RE: How to setup multiple JAXRS server endpoints



JPU> Hi Andriy,



JPU> As a test I removed all JAX-RS endpoints that use Swagger v2 annotations
JPU> from my configuration file (see attachment).

JPU> So I've now only 1 JAX-RS endpoint, fully annotated with Swagger v3
JPU> annotations, using the OpenApiFeature i.o. Swagger2Feature.

JPU> If I run my server with this configuration I only get the (working) *WADL*
JPU> and *OpenAPI* endpoints, no Swagger UI endpoint:





JPU> So there is some configuration missing to detect/activate the Swagger
JPU> endpoint. When I look at the samples that come with the distribution of CXF
JPU> (I am using v3.5.6) nothing special seems to be configured to activate this?

JPU> Do you have any idea how the SwaggerUiService is picked up when loading?



JPU> J.P.



JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: dinsdag 11 juli 2023 3:44
JPU> To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
JPU> Subject: Re: How to setup multiple JAXRS server endpoints



JPU> Hi Jean,



JPU> I guess you figured one issue, swagger.json -> openapi.json, but to be
JPU> honest we have never tested or envisioned the application that would use
JPU> OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same time, I am afraid this is
JPU> just not supported. You may get things back on track when going with
JPU> OpenAPI 3.0 for all services.



JPU> Thank you.



JPU> Best Regards,

JPU>     Andriy Redko





>> Hi Andriy,







>> I am trying to trace the difference in handling with another

>> application where I’ve got only one CXF service endpoint that uses

>> swagger v3 openapi annotations.



>> There I see that when handling the Swagger page request (

>> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json) the

>> JAXRSInInterceptor is calling:







>> *JAXRSUtils.**getRootResources*(Message message)







>> It contains 4 entries:



>>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint

>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

>>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService















>> On the application described below with the service ‘oidcsim’ when

>> calling the swagger page request

>> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the

>> result of the getRootResources doesn’t contain the ClassResourceInfo ‘

>> SwaggerUiService’. It only contains 3 entries:



>>    - (twice) OidcProviderApiServiceImpl (my service endpoint)

>>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource







>> The SwaggerUiService is the one that is configured to handle the
JPU> ‘api-docs’

>> path-request. Since it is missing the request is tried to match with

>> the other two resources but fails, hence ‘NOT FOUND’ exception.







>> I can’t trace back where these rootResources are set and why the

>> SwaggerUiService’ isn’t listed.







>> J.P.



>> *From:* Jean Pierre URKENS <je...@devoteam.com>

>> *Sent:* maandag 10 juli 2023 13:43

>> *To:* 'Andriy Redko' <dr...@gmail.com>

>> *Subject:* RE: How to setup multiple JAXRS server endpoints







>> Andriy,







>> I am trying to switch from Swagger v2 to OpenApi v3 annotations

>> basically because my starting point is an OpenApi v3.0.7 yaml file

>> description and OpenAPI seems to be the way forward.



>> For applications where I have only one CXF JAX-RS endpoint exposed I

>> had no problems converting. However as soon as there are multiple

>> endpoints I run into troubles.







>> So, to recall, I've an application exposing 3 JAX-RS endpoints that

>> where previously annotated with swagger v2 annotations (i.e. package

>> io.swagger.annotations.*) which I migrated to



>> swagger v3 annotations (package io.swagger.v3.oas.annotations.*). In

>> accordance I altered my CXF JAX-RS endpoint configuration from (only

>> showing relevant parts, see attachment for full setup):







>>                <!-- CXF Swagger2Feature -->



>>                <bean id="SwaggerUiConfigOidcApi"

>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>>                               <property name="queryConfigEnabled"



>>                               <property name="url"

>> value="/op/services/oidcsim/swagger.yaml"/>



>>                </bean>



>>                <bean id="Swagger2FeatureOidcApi"

>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">



>>                               <property name="basePath"

>> value="/op/services/oidcsim"/>



>>                               <property name="usePathBasedConfig"



>>                               <property name="resourcePackage"

>> value="be.dvtm.aeo.op.oidc"/>



>>                               <property name="supportSwaggerUi"



>>                               <property name="swaggerUiConfig"

>> ref="SwaggerUiConfigOidcApi"/>



>>                </bean>



>>                <jaxrs:server id="OidcProviderApiServer"

>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>>                               ....



>>                               <jaxrs:features>



>>                                              <ref

>> bean="Swagger2FeatureOidcApi" />



>>                               </jaxrs:features>



>>                               ...



>>                </jaxrs:server>







>> TO:



>>                <!-- CXF OpenAPIFeature -->



>>                <bean id="OidcSwaggerUiConfig"

>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>>                               <property name="queryConfigEnabled"



>>                               <property name="url"

>> value="openapi.json"/>



>>                </bean>



>>                <bean id="OidcOpenApiFeature"

>> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">



>>                               <property name="supportSwaggerUi"



>>                               <property name="swaggerUiConfig"

>> ref="OidcSwaggerUiConfig"/>



>>                               <property name="swaggerUiVersion"



>>                               <property name="scan" value="false"/>



>>                               <property name="useContextBasedConfig"



>>                               <property name="resourcePackages"

>> value="be.dvtm.aeo.op.oidc"/>



>>                </bean>



>>                <jaxrs:server id="OidcProviderApiServer"

>> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>>                               ....



>>                               <jaxrs:features>



>>                                              <ref
JPU> bean="OidcOpenApiFeature"



>>                               </jaxrs:features>



>>                               ...



>>                </jaxrs:server>











>> Now when starting my application and navigating to the root part "

>> http://localhost:localPort/op/services" I get an overview of all my

>> endpoints:







>> Now there are 3 RESTful service endpoints setup:



>>    1. ‘oidcsim’ which I switched to swagger v3 annotations

>>    2. ‘openapi’ currently still swagger v2 annotations

>>    3. ‘sdx’ currently still swagger v2 annotations







>> all endpoints work except for the ‘swagger endpoint address for the

>> oidcsim

>> endpoint:

>> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services/oi

>> dcsim/swagger.json



>> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*

>> endpoint of the oidcsim resource. I am getting an error (the value of

>> the ‘url’ query parameter isn’t relevant):







>>         “WebApplicationException has been caught, status: 404,

>> message: HTTP 404 Not Found”







>> When I try (without the ‘/oidcsim’ context):

>> http://l-p53-008:8081/op/services/api-docs I get:



>>                “No service was found.”







>> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs

>> doesn’t exist, where as the endpoint

>> http://l-p53-008:8081/op/services/api-docs does exist but no service
JPU> description is found?



>> Of course my intention is to get working, as previously with the

>> swagger v2 setup for which I then specifically added the

>> *Swagger2Feature* config

>> parameters:



>>                               <property name="basePath"

>> value="/op/services/oidcsim"/>



>>                               <property name="usePathBasedConfig"







>> But I don’t find the according configuration options for the

>> *OpenApiFeature* class or whether I should configure this in another way.







>> Any suggestions on this?







>> Regards,







>> J.P.











>> -----Original Message-----

>> From: Andriy Redko <dr...@gmail.com>

>> Sent: donderdag 25 mei 2023 2:27

>> To: Jean Pierre URKENS <je...@devoteam.com>;

>> dev@cxf.apache.org

>> Subject: Re: How to setup multiple JAXRS server endpoints







>> Hi Jean,







>> You may run into Swagger JAX-RS scanner limitations, as far as I can

>> tell - it checks class annotations for SwaggerDefinition, does not

>> traverse the hierarchy [1].







>> [1]

>> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-j

>> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194







>> Best Regards,



>>     Andriy Redko







>>>  RE: How to setup multiple JAXRS server endpoints







>>> Still one question );







>>> The generated swagger file doesn’t take into account the



>>> @SwaggerDefintion on my interface classes?







>>> As a test I looked at



>>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma



>>> in/release/samples/jax_rs/description_swagger2_web**



>>> and** modified** sample2*



>>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma



>>> in/release/samples/jax_rs/description_swagger2_web



>>> and modified sample2> as follows:







>>>    @Path("/sample2")







>>>       @Api(value = "/sample2",authorizations=



>>>       {@Authorization(value="bearer")},description = "Sample2

>> (modified) JAX-RS



>>>       service with Swagger documentation")







>>>       @SwaggerDefinition(







>>>               info = @Info(







>>>                       description = "Sample2 server",







>>>                       version="1.0",







>>>                       title = "Test2",







>>>                       contact = @Contact(name = "J.P. Urkens",email = "



>>>       *jean-pierre.urkens@devoteam.com* <

>> jean-pierre.urkens@devoteam.com>



>>>       ")),







>>>               securityDefinition =



>>>       @SecurityDefinition(apiKeyAuthDefinitions=



>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="Au

>> thorization",description="Use*



>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer



>>>       &lt;accessToken&gt;'")})







>>>       )







>>>       public class Sample2 {...}







>>> This correctly generates the ‘securityDefintions’ in the swagger file.







>>> If include the same @SwaggerDefinition and the authorizations on



>>> the @Api annotation as above in my interface classes then the



>>> generated swagger file doesn’t contain the ‘securityDefintions’ ?







>>> Any idea what I might be missing?







>>> Regards,







>>> J.P.







>>> -----Original Message-----



>>> From: Jean Pierre URKENS <je...@devoteam.com>



>>> Sent: dinsdag 23 mei 2023 12:52



>>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <





>>> Subject: RE: How to setup multiple JAXRS server endpoints







>>> Hi Andriy,







>>> I added the parameter usePathBasedConfig=true to the



>>> Swagger2Feature bean declarations but still it does generate an



>>> empty swagger.yaml for interfaces KmopResources and



>>> KmopDienstverlener although I noticed that for these interfaces the



>>> @Path() annotation was commented out (as I included it in the



>>> server declaration). After providing an empty @Path("") declaration

>>> on

>> the API interface classes everything worked.







>>> Thanks for the support.







>>> -----Original Message-----







>>> From: Andriy Redko <dr...@gmail.com>







>>> Sent: dinsdag 23 mei 2023 3:42







>>> To: Jean Pierre URKENS <je...@devoteam.com>;



>>> dev@cxf.apache.org







>>> Subject: Re: How to setup multiple JAXRS server endpoints







>>> Hi Jean,







>>> The main problem to configure Swagger property in your particular



>>> case is that the server address is not "known" or "introspectable"

>>> for

>> Swagger.



>>> Intuitively, it has to be set manually using basePath to the,



>>> essentially, the server address







>>> part:







>>>  - /op/services/accounts







>>>  - /op/services/resources







>>>  - /op/services/dienstverlener







>>> You could read more about other Swagger properties you have asked here:



>>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte



>>> gration-and-Configuration#configuration-properties







>>> You definitely need to set usePathBasedConfig to "true" otherwise



>>> you will see the same Swagger specs for all servers. We have a



>>> sample here which uses 2 jaxrs:server







>>> instances:



>>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai



>>> n/release/samples/jax_rs/description_swagger2_web







>>> Regarding SwaggerUI, I think the value for each of those should be



>>> set to,



>>> respectively:







>>>  - /op/services/accounts/swagger.yaml







>>>  - /op/services/resources/swagger.yaml







>>>  - /op/services/dienstverlener/swagger.yaml







>>> I believe this is matching your settings already, except the



>>> usePathBasedConfig part. The example referred above could be



>>> helpful, my apologies if I missed something, there are quite a lot



>>> of questions :-) The fact that the generated Swagger specification



>>> is empty is unexpected - it should not happen when JAX-RS resources

>> are properly configured.







>>> Thank you.







>>> Best Regards,







>>>     Andriy Redko







>>>>  RE: How to setup multiple JAXRS server endpoints







>>>> Hi Andriy,







>>>> I am not quite understanding how to correctly configure the



>>> Swagger2Feature.







>>>> Referring to the attached cxf-endpoints configuration I (as a



>>>> test)







>>>> created







>>>> 3 JAXRS server instances:







>>>> 1.      A* KmopApiServer* server for the*







>>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving







>>>> requests for URI path:







>>>>        * <protocol>**//<host:<port>/op/services/accounts*







>>>>    ‘op’  = root path of the web application







>>>>             ‘services’ = servlet path of the CXF-servlet







>>>>       The address of the server is set to ‘/accounts’ and the



>>>> @Path(…)







>>>>       annotation on the interface class was cleared.







>>>> 2.      A* Kmop**Resources**ApiServer* server for the*

>> be.dvtm.aeo.op.*







>>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving







>>>> requests for URI path:







>>>>        * <protocol>**//<host:<port>/op/services/**resources*







>>>> The address of the server is set to ‘/resources’ and the @Path(…)







>>>> annotation on the interface class was cleared.







>>>> 3.      A* Kmop**Dienstverlener**Server* server for the*



>>> be.dvtm.aeo.op.*







>>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving







>>>> requests for URI path:







>>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*







>>>> The address of the server is set to ‘/dienstverlener’ and the







>>>> @Path(…) annotation on the interface class was cleared.







>>>> For each of these server instances I’ve set the Swagger2Feature







>>>> with configuration as indicated in the attached cxf-endpoints.xml.







>>>> With regard to the configurations for the Swagger2Feature I’ve the







>>>> following questions:







>>>> a)      Referring to *

>> https://cxf.apache.org/docs/swagger2feature.html*







>>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you







>>>> clarify on the following configuration parameters:







>>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘







>>>> /op/services’) or to the JAX-RS server instance (e.g.







>>>> ‘/op/services/accounts’) or still something else? Is it used to







>>>> resolve service classes or is it just for documentation in the



>>>> swagger



>>> file?







>>>> *ii.    ** resourcePackage* – the description mentions ‘package names’







>>>> while the default mentions ‘service classes’? Service 2 and 3



>>>> above







>>>> are within the same package (generated from the same yaml







>>>> specification that included both interfaces).







>>>> *iii.   ** ig**noreRoutes* – is this taken into account when







>>>> scanAllResources=false?







>>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter

>> value







>>>> (cf. question ‘a’)?







>>>> b)      What would be the correct URL to generate a swagger.yaml

>>>> file



>>> for







>>>> each of the above interfaces? Initially I called:







>>>> *i.     **



>>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*







>>>> *ii.    **



>>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*







>>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*







>>>> *lener/swagger.yaml*







>>>>    All three requests delivered the same yaml specification,



>>>> namely



>>> the one







>>>>       for interface* KmopApiServer*?







>>>> c)      I tried to debug the processing of the requests under ‘b)’

>>>> and



>>> this







>>>> is done by the class JAXRSInterceptor#processRequest where the







>>>> MessageImpl object for request “ii.” looks like the one attached.







>>>> It finds 3 resource







>>>> classes:







>>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl







>>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource







>>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService







>>>> è       It matches the request to resource*



>>> Swagger2ApiListingResource* with







>>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*







>>>> process(…)* method.







>>>> è       Here it seems to go wrong. It generates a

>> SwaggerContextService







>>>> having basePath=/op/services/resources/,swaggerConfig=null,







>>>> usePathBasedConfig=null and then calls







>>>> SwaggerContextService.getSwagger()







>>>> which returns the Swagger definition for interface KmopApiServer?







>>>> It looks like it caches generated swagger definitions based on a







>>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the







>>>> same for all 3 interfaces as usePathBasedConfig=null







>>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is







>>>> derived from the ServletConfig parameter







>>>> ‘swagger.use.path.based.config’.* So should this be set on the







>>>> declaration of the CXFServlet** in web.xml?*







>>>> è       Actually the SwaggerConfig, the JaxrsScanner and the

>>>> generated



>>> Swagger







>>>> are cached using keys like







>>>> ‘swagger.config.id.[default|baseUriPath]’, ‘







>>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’



>>> is only done when usePathBasedconfig=true.







>>>> è       If I patch this to true then configIdKey=’







>>>> swagger.config.id./op/services/resources/’ and no swagger entry is







>>>> cached for this key so it will generate a new one. Again by







>>>> patching







>>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru



>>>> e







>>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”







>>>> è       Again Scanners are cached and if usePathBasedConfig=null it



>>> will use







>>>> the one cached under  ‘swagger.scanner.id.default’ and this again







>>>> returns the swagger definition for the KmopApiService interface.







>>>> è       So patching usePathBasedConfig=true will return a new one







>>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner







>>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘







>>>> which is correct. It will generate a new (but empty) Swagger object.







>>>> è       Next Swagger2ApiListingResource will call the







>>>> customizer.customize(s), which still isn’t putting anything new in







>>>> the Swagger object. Should it or should the next step do this?







>>>> è       Next BaseApiListingResource#getListing(…) is called which on



>>> its







>>>> turn calls getListingYamlResponse(..)







>>>> è       The final result is a swagger.yaml document with following



>>> content:







>>>>    swagger: "2.0"







>>>>       info:







>>>>         license:







>>>>           name: "Apache 2.0 License"







>>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html







>>>>       basePath: "/op/services/resources"







>>>>        So basically an empty swagger file.







>>>> d)      The usePathBasedConfig is derived from the ServletConfig



>>> parameter ‘







>>>> swagger.use.path.based.config’. Without this parameter set to true







>>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger







>>>> object.* So should this be set on the declaration of the







>>>> CXFServlet** in web.xml?*







>>>> The majority in this processing happens in the library







>>>> swagger-jaxrs-v1.6.10 which is included as a dependency on



>>> cxf-rt-rs-service-description-swagger.







>>>> Even if I patch usePathBasedConfig=true about everywhere where I







>>>> met this it still doesn’t generate a correct swagger.yaml. Am I







>>>> still missing some configuration parameter?







>>>> Any suggestions on how to resolve this would be welcome.







>>>> Regards,







>>>> J.P. Urkens











































>>>> <<...>> <<...>>







>>>> -----Original Message-----







>>>> From: Andriy Redko <dr...@gmail.com>







>>>> Sent: maandag 8 mei 2023 23:15







>>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev







>>>> List <













>>>> Subject: Re: How to setup multiple JAXRS server endpoints







>>>> Hi Jean,







>>>> Indeed the way you would like to do that is somewhat tricky.







>>>>> So I tried to keep the @Path declaration on the interface classes



>>>>> but







>>>> changed them to @Path(“”). That does seems to work except the







>>>> swagger stuff no longer correctly works.







>>>> This is one of the possible options but OpenAPI/Swagger gets







>>>> confused for a







>>>> reason: the path is now implicit (not in the spec).







>>>> So how about this option:







>>>>  - use only one JAX-RS server (address "/")







>>>>  - host both resources but use @Path("accounts") and







>>>> @Path("resources") on them respectively











>>>> I see that for @Path("accounts") you need to apply the







>>>> "kmopApiAuthorizationFilter", that could be done using







>>>> DynamicFeature [1], [2]. If this is not the option and you would







>>>> prefer to use 2 separate JAX-RS servers, you may need to provide







>>>> your own instance of Swagger2Customizer [3], [4] which allows to







>>>> transform the OpenAPI/Swagger on the fly. Please let me know if



>>>> that



>>> would it work for you, thank you.







>>>> [1]







>>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic



>>>> F







>>>> eature.html







>>>> [2]







>>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born



>>>> -







>>>> equal.html







>>>> [3]







>>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger



>>>> /







>>>> Swagger2Customizer.html







>>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has







>>>> customizer







>>>> property)











>>>> Best Regards,







>>>>     Andriy Redko







>>>>> Hi Andriy,







>>>>> I am again getting into trouble with server endpoint declarations.







>>>>> Now







>>>> because I am adding additional JAX-RS endpoints.







>>>>> The issue is with:







>>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration

>>>>> in







>>>> combination with







>>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the

>>>>> web.xml







>>>> in combination with







>>>>> 3.      The @Path declaration in the interface class in combination

>>>>> with







>>>>> 4.      The @Path declaration on the interface method in

>>>>> combination

>> with







>>>>> So what I had is that my web application deployed under baseUlr 'op'







>>>>> had







>>>> one JAXRS server endpoint with declarations like:







>>>>> 1.      <jaxrs:server id="restServer"







>>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">







>>>>> 2.      <url-pattern>/services/*</url-pattern>







>>>>> 3.      @Path("accounts") on the public interface class







>>>>> 4.      @Path("/{authorisationId}/customerFund") on the

>>>>> customerFund







>>>> interface method







>>>>> A valid API call would thus be e.g.:







>>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/cu

>>>>> s



>>>>> t







>>>>> o







>>>>> merFund







>>>>> And this works correctly.







>>>>> We're now introducing additional JAX-RS service endpoints and now I







>>>>> am







>>>> running into problems. This second endpoint was declared with:







>>>>> 1.      <jaxrs:server id="resourceServer"







>>>> basePackages="be.dvtm.aeo.op.resources" address="/">







>>>>> 2.      <url-pattern>/services/*</url-pattern>







>>>>> 3.      @Path("resources") on the public interface class







>>>>> 4.      @Path("/NACE") on the NACE interface method







>>>>> So here a valid API call woud be:







>>>> https://<hostname>:<port>/op/services/resources/NACE.







>>>>> The problem is that I can not declare two <jaxrs:server> entries



>>>>> with







>>>>> the







>>>> same ‘address’ as it throws the exception:







>>>>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:







>>>> There is an endpoint already running on /.







>>>>>  So I tried changing the addresses to:







>>>>> ·       address=”accounts” for the restServer







>>>>> ·       address=”resources” for the resourceServer







>>>>> But to keep the API-call URLs the same I removed the @Path







>>>>> declaration on







>>>> the interface classes. By doing so the <jaxrs:server> bean







>>>> declarations no longer loads successfully.







>>>>> So I tried to keep the @Path declaration on the interface classes



>>>>> but







>>>> changed them to @Path(“”). That does seems to work except the







>>>> swagger stuff no longer correctly works.







>>>>> So what is the decent way to setup multiple JAX-RS server endpoints







>>>>> where







>>>> each server has its own configuration regarding supported features:







>>>>> ·       own validation







>>>>> ·       own object and exception mappings







>>>>> ·       own swagger file generation







>>>>> ·       own logging (in separate file if possible)







>>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in







>>>>> cooperation







>>>> with swager-ui v4.5.0.







>>>>> Below the declarations of my endpoints <<...>> Thanks for any advice.







>>>>> Regards,







>>>>> J.P. Urkens







>>>>> -----Original Message-----







>>>>> From: Andriy Redko <dr...@gmail.com>







>>>>> Sent: zaterdag 18 juni 2022 1:12







>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;







>>>>> issues@cxf.apache.org; dev@cxf.apache.org







>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,







>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'







>>>>> Correct, so in the relative form like address="/<something>", the







>>>>> JAX-RS







>>>> endpoint path would be:







>>>>>     <baseUrl>/<servlet path







mapping>>>>>>/<address>/[@ApplicationPath]/[@Path]







>>>>> The @ApplicationPath is optional in this case.







>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'







>>>>> The JAX-WS is very different from JAX-RS, essentially the action







>>>>> comes







>>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/







>>>> (@Path / @ApplicationPath are not relevant there).







>>>>>> Question: Because now address="/" is set for the jaxrs:server will







>>>>>> it







>>>>>> also inspect requests targeted for the jaxws service as those







>>>>>> requests have start with the same path '/<basePath>/services/...







>>>>> This is a good question, I have not done it myself but I think it







>>>>> should







>>>> work:







>>>>> the servlet dispatches according to registered services, in this







>>>>> regard







>>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?



>>> Thank you.







>>>>> Best Regards,







>>>>>     Andriy Redko







>>>>>> Hi Andriy,







>>>>>> Using address="/" seems to work but still I don't understand how



>>>>>> the







>>>>>> following work together:







>>>>>>  - path specification in servlet mapping for the CXF servlet







>>>>>> (org.apache.cxf.transport.servlet.CXFServlet)







>>>>>>  - the 'address' attribute on the jaxrs:server bean declaration







>>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the







>>>>>> service API description Say I've two services with (relateive to



>>>>>> the







>>>>>> host) url's:







>>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'







>>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'







>>>>>> How do I configure above 3 aspects? Currently I have (working):







>>>>>> 1.for the jaxrs:server endpoint:







>>>>>>         - servlet path mapping: '/services/*'







>>>>>>                - jaxrs-server address attribute: address="/"







>>>>>>                - @Path annotation: @Path("service1") 2.For the



>>>>>> jaxws







>>>>>> service endpoint:







>>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS







>>>>>> requests are handleb by the same CXF servle)







>>>>>>                - jaxws:endpoint server address attribute:







>>>>>> address="/service2"







>>>>>>                - @WebService(name="service2") A correct request

>>>>>> for







>>>>>> '1' would be '/basePath>/services/service1/<ID>'.







>>>>>> A correct request for '2' would be '/basePath>/services/service2'.







>>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:







>>>>>>         - the server address attribute







>>>>>>         - The API annotation (@Path or @Webservice) The JAXWS



>>>>>> server







>>>>>> address attribute doesn't seem to interfere with the @Webservice







>>>>>> annotation. While the jaxrs server address attribute does seem to







>>>>>> interfere with the @Path annotation. I would have expected the



>>>>>> jaxrs







>>>>>> server aspects to be configured as:







>>>>>>         - servlet path mapping: '/services/*'







>>>>>>                - jaxrs-server address attribute: address="/service1"







>>>>>>                - @Path annotation: @Path("service1") but then a







>>>>>> valid







>>>>>> request would be







>>>>>>> /services/service1/service1/<ID>'.







>>>>>> For both the 'address' attribute is relative to the servlet path.







>>>>>> The @Path Javadoc mentions that this path is relative to the







>>>>>> ApplicationPath which thus seems to be relative to the

>>>>>> jaxrs-server







>>>>>> address attribute. As for @Webservice it doesnn't seem to be







>>>>>> url-path







>>>> related.







>>>>>> Question: Because now address="/" is set for the jaxrs:server will







>>>>>> it







>>>>>> also inspect requests targeted for the jaxws service as those







>>>>>> requests have start with the same path '/<basePath>/services/...'.







>>>>>> Albeit somewhat confusing.







>>>>>> J.P.







>>>>>> -----Original Message-----







>>>>>> From: Andriy Redko <dr...@gmail.com>







>>>>>> Sent: dinsdag 14 juni 2022 1:08







>>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;







>>>>>> issues@cxf.apache.org; dev@cxf.apache.org







>>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi

>>>>>> Jean,







>>>>>> Indeed, the jaxrs:server does not expect address to be omitted,

>>>>>> you







>>>>>> could use the "/" (and I believe an empty string would also make it):







>>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...







>>>>>> </jaxrs:server>







>>>>>> Thank you.







>>>>>> Hope it helps.







>>>>>> Best Regards,







>>>>>>     Andriy Redko







>>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean







>>>>>>> declarations







>>>>>>> like:







>>>>>>>      <jaxrs:server id="restServer" basePackages="xxx">







>>>>>>>            <jaxrs:serviceBeans>







>>>>>>>                 <ref bean="TestApi" />







>>>>>>>            </jaxrs:serviceBeans>







>>>>>>>            <jaxrs:providers>







>>>>>>>                 <…/>







>>>>>>>            </jaxrs:providers>







>>>>>>>            <jaxrs:features>







>>>>>>>                 <… />







>>>>>>>            </jaxrs:features>







>>>>>>>            <jaxrs:inInterceptors>







>>>>>>>                 <… />







>>>>>>>            </jaxrs:inInterceptors>







>>>>>>>            <jaxrs:outInterceptors>*







>>>>>>>                 <**…**/>*







>>>>>>>            </jaxrs:outInterceptors>*







>>>>>>>      </jaxrs:server>











>>>>>>> Here my “TestApi” bean interface is declared like:







>>>>>>>       @Path("accounts")







>>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)







>>>>>>>        @Produces(MediaType.*APPLICATION_JSON*)







>>>>>>>        public interface TestApi {







>>>>>>>          …







>>>>>>>        }







>>>>>>> And CXF is triggered via a servlet configuration like:







>>>>>>>      <servlet>







>>>>>>>              <display-name>CXF Servlet</display-name>







>>>>>>>              <servlet-name>CXFServlet</servlet-name>







>>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servl

>>>>>>> e







>>>>>>> t













>>>>>>>        </servlet>







>>>>>>>        <servlet-mapping>







>>>>>>>              <servlet-name>CXFServlet</servlet-name>







>>>>>>>              <url-pattern>/services/*</url-pattern>







>>>>>>>        </servlet-mapping>











>>>>>>> Because I’ve got the @Path declaration on the interface type I’ve







>>>>>>> omitted







>>>>>>> the address=”accounts” attribute on the jaxrs:server declaration







>>>>>>> since otherwise







>>>>>>> I noticed that the server would be listening to







>>>>>>> /basepath/services/ accounts/accounts/…).







>>>>>>> Now this configuration works perfectly, only when shutting down







>>>>>>> the application server cxf calls







>>>>>>>         ServerImpl#destroy()







>>>>>>> which delegates (via Obeservable) to







>>>>>>> AbstractHTTPDestination#deactivate()







>>>>>>> which calls







>>>>>>> registry.removeDestination(path).







>>>>>>> This path is null (no ‘address’ specified on jaxrs:server







>>>>>>> declaration) and results in a NPE on the registry Map.







>>>>>>> This causes an unclean shutdown of my server.







>>>>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?







>>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration







>>>>>>> correctly interact with the @Path parameter on the API interface?







>>>> <<...>>


RE: How to setup multiple JAXRS server endpoints

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
After some code investigation:



OpenApiFeature implements SwaggerUiSupport and in its
portable#registerSwaggerUiResources(…) method it will call
SwaggerUiSupport#getSwaggerUi(…) which will register the SwaggerUiService.



I have put breakpoints on:

   - OpenApiFeature$Portable#initiliaze(…)
   - SwaggerUiService constructor
   - SwaggerUiSupport#getSwaggerUi(…)



but none of them are hit when starting my application?



Although the (spring) logging shows all beans in my cxf-endpoints.xml have
been created?

The *WADL* and *OpenAPI* endpoints to get the specification work.

Even the actual endpoint seems to work although I didn’t hit any of the
breakpoint?



CXF, also doesn’t seem to log a lot, I am hardly getting any log entries
although log level I set to DEBUG.

My logging (except wire message logging) for cxf is setup correctly (I
think):

   - ../META-INF/cxf/org.apache.cxf.Logger contains the line
   ‘org.apache.cxf.common.logging.Slf4jLogger’
   - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and
   reload4j-1.2.19.jar are on the classpath
   - the log4j.properties file contains the line:
   ‘log4j.logger.org.apache.cxf=DEBUG’



There are no special instructions mentioned on
https://cxf.apache.org/docs/general-cxf-logging.html so the above should
work (it works for all other packages I use in my application).



J.P.

*From:* Jean Pierre URKENS <je...@devoteam.com>
*Sent:* dinsdag 11 juli 2023 9:58
*To:* 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <
dev@cxf.apache.org>
*Subject:* RE: How to setup multiple JAXRS server endpoints



Hi Andriy,



As a test I removed all JAX-RS endpoints that use Swagger v2 annotations
from my configuration file (see attachment).

So I've now only 1 JAX-RS endpoint, fully annotated with Swagger v3
annotations, using the OpenApiFeature i.o. Swagger2Feature.

If I run my server with this configuration I only get the (working) *WADL*
and *OpenAPI* endpoints, no Swagger UI endpoint:





So there is some configuration missing to detect/activate the Swagger
endpoint. When I look at the samples that come with the distribution of CXF
(I am using v3.5.6) nothing special seems to be configured to activate this?

Do you have any idea how the SwaggerUiService is picked up when loading?



J.P.



-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: dinsdag 11 juli 2023 3:44
To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
Subject: Re: How to setup multiple JAXRS server endpoints



Hi Jean,



I guess you figured one issue, swagger.json -> openapi.json, but to be
honest we have never tested or envisioned the application that would use
OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same time, I am afraid this is
just not supported. You may get things back on track when going with
OpenAPI 3.0 for all services.



Thank you.



Best Regards,

    Andriy Redko





> Hi Andriy,







> I am trying to trace the difference in handling with another

> application where I’ve got only one CXF service endpoint that uses

> swagger v3 openapi annotations.



> There I see that when handling the Swagger page request (

> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json) the

> JAXRSInInterceptor is calling:







> *JAXRSUtils.**getRootResources*(Message message)







> It contains 4 entries:



>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint

>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService















> On the application described below with the service ‘oidcsim’ when

> calling the swagger page request

> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the

> result of the getRootResources doesn’t contain the ClassResourceInfo ‘

> SwaggerUiService’. It only contains 3 entries:



>    - (twice) OidcProviderApiServiceImpl (my service endpoint)

>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource







> The SwaggerUiService is the one that is configured to handle the
‘api-docs’

> path-request. Since it is missing the request is tried to match with

> the other two resources but fails, hence ‘NOT FOUND’ exception.







> I can’t trace back where these rootResources are set and why the

> SwaggerUiService’ isn’t listed.







> J.P.



> *From:* Jean Pierre URKENS <je...@devoteam.com>

> *Sent:* maandag 10 juli 2023 13:43

> *To:* 'Andriy Redko' <dr...@gmail.com>

> *Subject:* RE: How to setup multiple JAXRS server endpoints







> Andriy,







> I am trying to switch from Swagger v2 to OpenApi v3 annotations

> basically because my starting point is an OpenApi v3.0.7 yaml file

> description and OpenAPI seems to be the way forward.



> For applications where I have only one CXF JAX-RS endpoint exposed I

> had no problems converting. However as soon as there are multiple

> endpoints I run into troubles.







> So, to recall, I've an application exposing 3 JAX-RS endpoints that

> where previously annotated with swagger v2 annotations (i.e. package

> io.swagger.annotations.*) which I migrated to



> swagger v3 annotations (package io.swagger.v3.oas.annotations.*). In

> accordance I altered my CXF JAX-RS endpoint configuration from (only

> showing relevant parts, see attachment for full setup):







>                <!-- CXF Swagger2Feature -->



>                <bean id="SwaggerUiConfigOidcApi"

> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>                               <property name="queryConfigEnabled"



>                               <property name="url"

> value="/op/services/oidcsim/swagger.yaml"/>



>                </bean>



>                <bean id="Swagger2FeatureOidcApi"

> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">



>                               <property name="basePath"

> value="/op/services/oidcsim"/>



>                               <property name="usePathBasedConfig"



>                               <property name="resourcePackage"

> value="be.dvtm.aeo.op.oidc"/>



>                               <property name="supportSwaggerUi"



>                               <property name="swaggerUiConfig"

> ref="SwaggerUiConfigOidcApi"/>



>                </bean>



>                <jaxrs:server id="OidcProviderApiServer"

> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>                               ....



>                               <jaxrs:features>



>                                              <ref

> bean="Swagger2FeatureOidcApi" />



>                               </jaxrs:features>



>                               ...



>                </jaxrs:server>







> TO:



>                <!-- CXF OpenAPIFeature -->



>                <bean id="OidcSwaggerUiConfig"

> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>                               <property name="queryConfigEnabled"



>                               <property name="url"

> value="openapi.json"/>



>                </bean>



>                <bean id="OidcOpenApiFeature"

> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">



>                               <property name="supportSwaggerUi"



>                               <property name="swaggerUiConfig"

> ref="OidcSwaggerUiConfig"/>



>                               <property name="swaggerUiVersion"



>                               <property name="scan" value="false"/>



>                               <property name="useContextBasedConfig"



>                               <property name="resourcePackages"

> value="be.dvtm.aeo.op.oidc"/>



>                </bean>



>                <jaxrs:server id="OidcProviderApiServer"

> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>                               ....



>                               <jaxrs:features>



>                                              <ref
bean="OidcOpenApiFeature"



>                               </jaxrs:features>



>                               ...



>                </jaxrs:server>











> Now when starting my application and navigating to the root part "

> http://localhost:localPort/op/services" I get an overview of all my

> endpoints:







> Now there are 3 RESTful service endpoints setup:



>    1. ‘oidcsim’ which I switched to swagger v3 annotations

>    2. ‘openapi’ currently still swagger v2 annotations

>    3. ‘sdx’ currently still swagger v2 annotations







> all endpoints work except for the ‘swagger endpoint address for the

> oidcsim

> endpoint:

> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services/oi

> dcsim/swagger.json



> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*

> endpoint of the oidcsim resource. I am getting an error (the value of

> the ‘url’ query parameter isn’t relevant):







>         “WebApplicationException has been caught, status: 404,

> message: HTTP 404 Not Found”







> When I try (without the ‘/oidcsim’ context):

> http://l-p53-008:8081/op/services/api-docs I get:



>                “No service was found.”







> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs

> doesn’t exist, where as the endpoint

> http://l-p53-008:8081/op/services/api-docs does exist but no service
description is found?



> Of course my intention is to get working, as previously with the

> swagger v2 setup for which I then specifically added the

> *Swagger2Feature* config

> parameters:



>                               <property name="basePath"

> value="/op/services/oidcsim"/>



>                               <property name="usePathBasedConfig"







> But I don’t find the according configuration options for the

> *OpenApiFeature* class or whether I should configure this in another way.







> Any suggestions on this?







> Regards,







> J.P.











> -----Original Message-----

> From: Andriy Redko <dr...@gmail.com>

> Sent: donderdag 25 mei 2023 2:27

> To: Jean Pierre URKENS <je...@devoteam.com>;

> dev@cxf.apache.org

> Subject: Re: How to setup multiple JAXRS server endpoints







> Hi Jean,







> You may run into Swagger JAX-RS scanner limitations, as far as I can

> tell - it checks class annotations for SwaggerDefinition, does not

> traverse the hierarchy [1].







> [1]

> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-j

> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194







> Best Regards,



>     Andriy Redko







>>  RE: How to setup multiple JAXRS server endpoints







>> Still one question );







>> The generated swagger file doesn’t take into account the



>> @SwaggerDefintion on my interface classes?







>> As a test I looked at



>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma



>> in/release/samples/jax_rs/description_swagger2_web**



>> and** modified** sample2*



>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma



>> in/release/samples/jax_rs/description_swagger2_web



>> and modified sample2> as follows:







>>    @Path("/sample2")







>>       @Api(value = "/sample2",authorizations=



>>       {@Authorization(value="bearer")},description = "Sample2

> (modified) JAX-RS



>>       service with Swagger documentation")







>>       @SwaggerDefinition(







>>               info = @Info(







>>                       description = "Sample2 server",







>>                       version="1.0",







>>                       title = "Test2",







>>                       contact = @Contact(name = "J.P. Urkens",email = "



>>       *jean-pierre.urkens@devoteam.com* <

> jean-pierre.urkens@devoteam.com>



>>       ")),







>>               securityDefinition =



>>       @SecurityDefinition(apiKeyAuthDefinitions=



> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="Au

> thorization",description="Use*



>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer



>>       &lt;accessToken&gt;'")})







>>       )







>>       public class Sample2 {...}







>> This correctly generates the ‘securityDefintions’ in the swagger file.







>> If include the same @SwaggerDefinition and the authorizations on



>> the @Api annotation as above in my interface classes then the



>> generated swagger file doesn’t contain the ‘securityDefintions’ ?







>> Any idea what I might be missing?







>> Regards,







>> J.P.







>> -----Original Message-----



>> From: Jean Pierre URKENS <je...@devoteam.com>



>> Sent: dinsdag 23 mei 2023 12:52



>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <





>> Subject: RE: How to setup multiple JAXRS server endpoints







>> Hi Andriy,







>> I added the parameter usePathBasedConfig=true to the



>> Swagger2Feature bean declarations but still it does generate an



>> empty swagger.yaml for interfaces KmopResources and



>> KmopDienstverlener although I noticed that for these interfaces the



>> @Path() annotation was commented out (as I included it in the



>> server declaration). After providing an empty @Path("") declaration

>> on

> the API interface classes everything worked.







>> Thanks for the support.







>> -----Original Message-----







>> From: Andriy Redko <dr...@gmail.com>







>> Sent: dinsdag 23 mei 2023 3:42







>> To: Jean Pierre URKENS <je...@devoteam.com>;



>> dev@cxf.apache.org







>> Subject: Re: How to setup multiple JAXRS server endpoints







>> Hi Jean,







>> The main problem to configure Swagger property in your particular



>> case is that the server address is not "known" or "introspectable"

>> for

> Swagger.



>> Intuitively, it has to be set manually using basePath to the,



>> essentially, the server address







>> part:







>>  - /op/services/accounts







>>  - /op/services/resources







>>  - /op/services/dienstverlener







>> You could read more about other Swagger properties you have asked here:



>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte



>> gration-and-Configuration#configuration-properties







>> You definitely need to set usePathBasedConfig to "true" otherwise



>> you will see the same Swagger specs for all servers. We have a



>> sample here which uses 2 jaxrs:server







>> instances:



>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai



>> n/release/samples/jax_rs/description_swagger2_web







>> Regarding SwaggerUI, I think the value for each of those should be



>> set to,



>> respectively:







>>  - /op/services/accounts/swagger.yaml







>>  - /op/services/resources/swagger.yaml







>>  - /op/services/dienstverlener/swagger.yaml







>> I believe this is matching your settings already, except the



>> usePathBasedConfig part. The example referred above could be



>> helpful, my apologies if I missed something, there are quite a lot



>> of questions :-) The fact that the generated Swagger specification



>> is empty is unexpected - it should not happen when JAX-RS resources

> are properly configured.







>> Thank you.







>> Best Regards,







>>     Andriy Redko







>>>  RE: How to setup multiple JAXRS server endpoints







>>> Hi Andriy,







>>> I am not quite understanding how to correctly configure the



>> Swagger2Feature.







>>> Referring to the attached cxf-endpoints configuration I (as a



>>> test)







>>> created







>>> 3 JAXRS server instances:







>>> 1.      A* KmopApiServer* server for the*







>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving







>>> requests for URI path:







>>>        * <protocol>**//<host:<port>/op/services/accounts*







>>>    ‘op’  = root path of the web application







>>>             ‘services’ = servlet path of the CXF-servlet







>>>       The address of the server is set to ‘/accounts’ and the



>>> @Path(…)







>>>       annotation on the interface class was cleared.







>>> 2.      A* Kmop**Resources**ApiServer* server for the*

> be.dvtm.aeo.op.*







>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving







>>> requests for URI path:







>>>        * <protocol>**//<host:<port>/op/services/**resources*







>>> The address of the server is set to ‘/resources’ and the @Path(…)







>>> annotation on the interface class was cleared.







>>> 3.      A* Kmop**Dienstverlener**Server* server for the*



>> be.dvtm.aeo.op.*







>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving







>>> requests for URI path:







>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*







>>> The address of the server is set to ‘/dienstverlener’ and the







>>> @Path(…) annotation on the interface class was cleared.







>>> For each of these server instances I’ve set the Swagger2Feature







>>> with configuration as indicated in the attached cxf-endpoints.xml.







>>> With regard to the configurations for the Swagger2Feature I’ve the







>>> following questions:







>>> a)      Referring to *

> https://cxf.apache.org/docs/swagger2feature.html*







>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you







>>> clarify on the following configuration parameters:







>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘







>>> /op/services’) or to the JAX-RS server instance (e.g.







>>> ‘/op/services/accounts’) or still something else? Is it used to







>>> resolve service classes or is it just for documentation in the



>>> swagger



>> file?







>>> *ii.    ** resourcePackage* – the description mentions ‘package names’







>>> while the default mentions ‘service classes’? Service 2 and 3



>>> above







>>> are within the same package (generated from the same yaml







>>> specification that included both interfaces).







>>> *iii.   ** ig**noreRoutes* – is this taken into account when







>>> scanAllResources=false?







>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter

> value







>>> (cf. question ‘a’)?







>>> b)      What would be the correct URL to generate a swagger.yaml

>>> file



>> for







>>> each of the above interfaces? Initially I called:







>>> *i.     **



>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*







>>> *ii.    **



>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*







>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*







>>> *lener/swagger.yaml*







>>>    All three requests delivered the same yaml specification,



>>> namely



>> the one







>>>       for interface* KmopApiServer*?







>>> c)      I tried to debug the processing of the requests under ‘b)’

>>> and



>> this







>>> is done by the class JAXRSInterceptor#processRequest where the







>>> MessageImpl object for request “ii.” looks like the one attached.







>>> It finds 3 resource







>>> classes:







>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl







>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource







>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService







>>> è       It matches the request to resource*



>> Swagger2ApiListingResource* with







>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*







>>> process(…)* method.







>>> è       Here it seems to go wrong. It generates a

> SwaggerContextService







>>> having basePath=/op/services/resources/,swaggerConfig=null,







>>> usePathBasedConfig=null and then calls







>>> SwaggerContextService.getSwagger()







>>> which returns the Swagger definition for interface KmopApiServer?







>>> It looks like it caches generated swagger definitions based on a







>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the







>>> same for all 3 interfaces as usePathBasedConfig=null







>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is







>>> derived from the ServletConfig parameter







>>> ‘swagger.use.path.based.config’.* So should this be set on the







>>> declaration of the CXFServlet** in web.xml?*







>>> è       Actually the SwaggerConfig, the JaxrsScanner and the

>>> generated



>> Swagger







>>> are cached using keys like







>>> ‘swagger.config.id.[default|baseUriPath]’, ‘







>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’



>> is only done when usePathBasedconfig=true.







>>> è       If I patch this to true then configIdKey=’







>>> swagger.config.id./op/services/resources/’ and no swagger entry is







>>> cached for this key so it will generate a new one. Again by







>>> patching







>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru



>>> e







>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”







>>> è       Again Scanners are cached and if usePathBasedConfig=null it



>> will use







>>> the one cached under  ‘swagger.scanner.id.default’ and this again







>>> returns the swagger definition for the KmopApiService interface.







>>> è       So patching usePathBasedConfig=true will return a new one







>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner







>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘







>>> which is correct. It will generate a new (but empty) Swagger object.







>>> è       Next Swagger2ApiListingResource will call the







>>> customizer.customize(s), which still isn’t putting anything new in







>>> the Swagger object. Should it or should the next step do this?







>>> è       Next BaseApiListingResource#getListing(…) is called which on



>> its







>>> turn calls getListingYamlResponse(..)







>>> è       The final result is a swagger.yaml document with following



>> content:







>>>    swagger: "2.0"







>>>       info:







>>>         license:







>>>           name: "Apache 2.0 License"







>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html







>>>       basePath: "/op/services/resources"







>>>        So basically an empty swagger file.







>>> d)      The usePathBasedConfig is derived from the ServletConfig



>> parameter ‘







>>> swagger.use.path.based.config’. Without this parameter set to true







>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger







>>> object.* So should this be set on the declaration of the







>>> CXFServlet** in web.xml?*







>>> The majority in this processing happens in the library







>>> swagger-jaxrs-v1.6.10 which is included as a dependency on



>> cxf-rt-rs-service-description-swagger.







>>> Even if I patch usePathBasedConfig=true about everywhere where I







>>> met this it still doesn’t generate a correct swagger.yaml. Am I







>>> still missing some configuration parameter?







>>> Any suggestions on how to resolve this would be welcome.







>>> Regards,







>>> J.P. Urkens











































>>> <<...>> <<...>>







>>> -----Original Message-----







>>> From: Andriy Redko <dr...@gmail.com>







>>> Sent: maandag 8 mei 2023 23:15







>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev







>>> List <













>>> Subject: Re: How to setup multiple JAXRS server endpoints







>>> Hi Jean,







>>> Indeed the way you would like to do that is somewhat tricky.







>>>> So I tried to keep the @Path declaration on the interface classes



>>>> but







>>> changed them to @Path(“”). That does seems to work except the







>>> swagger stuff no longer correctly works.







>>> This is one of the possible options but OpenAPI/Swagger gets







>>> confused for a







>>> reason: the path is now implicit (not in the spec).







>>> So how about this option:







>>>  - use only one JAX-RS server (address "/")







>>>  - host both resources but use @Path("accounts") and







>>> @Path("resources") on them respectively











>>> I see that for @Path("accounts") you need to apply the







>>> "kmopApiAuthorizationFilter", that could be done using







>>> DynamicFeature [1], [2]. If this is not the option and you would







>>> prefer to use 2 separate JAX-RS servers, you may need to provide







>>> your own instance of Swagger2Customizer [3], [4] which allows to







>>> transform the OpenAPI/Swagger on the fly. Please let me know if



>>> that



>> would it work for you, thank you.







>>> [1]







>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic



>>> F







>>> eature.html







>>> [2]







>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born



>>> -







>>> equal.html







>>> [3]







>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger



>>> /







>>> Swagger2Customizer.html







>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has







>>> customizer







>>> property)











>>> Best Regards,







>>>     Andriy Redko







>>>> Hi Andriy,







>>>> I am again getting into trouble with server endpoint declarations.







>>>> Now







>>> because I am adding additional JAX-RS endpoints.







>>>> The issue is with:







>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration

>>>> in







>>> combination with







>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the

>>>> web.xml







>>> in combination with







>>>> 3.      The @Path declaration in the interface class in combination

>>>> with







>>>> 4.      The @Path declaration on the interface method in

>>>> combination

> with







>>>> So what I had is that my web application deployed under baseUlr 'op'







>>>> had







>>> one JAXRS server endpoint with declarations like:







>>>> 1.      <jaxrs:server id="restServer"







>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">







>>>> 2.      <url-pattern>/services/*</url-pattern>







>>>> 3.      @Path("accounts") on the public interface class







>>>> 4.      @Path("/{authorisationId}/customerFund") on the

>>>> customerFund







>>> interface method







>>>> A valid API call would thus be e.g.:







>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/cu

>>>> s



>>>> t







>>>> o







>>>> merFund







>>>> And this works correctly.







>>>> We're now introducing additional JAX-RS service endpoints and now I







>>>> am







>>> running into problems. This second endpoint was declared with:







>>>> 1.      <jaxrs:server id="resourceServer"







>>> basePackages="be.dvtm.aeo.op.resources" address="/">







>>>> 2.      <url-pattern>/services/*</url-pattern>







>>>> 3.      @Path("resources") on the public interface class







>>>> 4.      @Path("/NACE") on the NACE interface method







>>>> So here a valid API call woud be:







>>> https://<hostname>:<port>/op/services/resources/NACE.







>>>> The problem is that I can not declare two <jaxrs:server> entries



>>>> with







>>>> the







>>> same ‘address’ as it throws the exception:







>>>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:







>>> There is an endpoint already running on /.







>>>>  So I tried changing the addresses to:







>>>> ·       address=”accounts” for the restServer







>>>> ·       address=”resources” for the resourceServer







>>>> But to keep the API-call URLs the same I removed the @Path







>>>> declaration on







>>> the interface classes. By doing so the <jaxrs:server> bean







>>> declarations no longer loads successfully.







>>>> So I tried to keep the @Path declaration on the interface classes



>>>> but







>>> changed them to @Path(“”). That does seems to work except the







>>> swagger stuff no longer correctly works.







>>>> So what is the decent way to setup multiple JAX-RS server endpoints







>>>> where







>>> each server has its own configuration regarding supported features:







>>>> ·       own validation







>>>> ·       own object and exception mappings







>>>> ·       own swagger file generation







>>>> ·       own logging (in separate file if possible)







>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in







>>>> cooperation







>>> with swager-ui v4.5.0.







>>>> Below the declarations of my endpoints <<...>> Thanks for any advice.







>>>> Regards,







>>>> J.P. Urkens







>>>> -----Original Message-----







>>>> From: Andriy Redko <dr...@gmail.com>







>>>> Sent: zaterdag 18 juni 2022 1:12







>>>> To: Jean Pierre URKENS <je...@devoteam.com>;







>>>> issues@cxf.apache.org; dev@cxf.apache.org







>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,







>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'







>>>> Correct, so in the relative form like address="/<something>", the







>>>> JAX-RS







>>> endpoint path would be:







>>>>     <baseUrl>/<servlet path







mapping>>>>>/<address>/[@ApplicationPath]/[@Path]







>>>> The @ApplicationPath is optional in this case.







>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'







>>>> The JAX-WS is very different from JAX-RS, essentially the action







>>>> comes







>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/







>>> (@Path / @ApplicationPath are not relevant there).







>>>>> Question: Because now address="/" is set for the jaxrs:server will







>>>>> it







>>>>> also inspect requests targeted for the jaxws service as those







>>>>> requests have start with the same path '/<basePath>/services/...







>>>> This is a good question, I have not done it myself but I think it







>>>> should







>>> work:







>>>> the servlet dispatches according to registered services, in this







>>>> regard







>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?



>> Thank you.







>>>> Best Regards,







>>>>     Andriy Redko







>>>>> Hi Andriy,







>>>>> Using address="/" seems to work but still I don't understand how



>>>>> the







>>>>> following work together:







>>>>>  - path specification in servlet mapping for the CXF servlet







>>>>> (org.apache.cxf.transport.servlet.CXFServlet)







>>>>>  - the 'address' attribute on the jaxrs:server bean declaration







>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the







>>>>> service API description Say I've two services with (relateive to



>>>>> the







>>>>> host) url's:







>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'







>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'







>>>>> How do I configure above 3 aspects? Currently I have (working):







>>>>> 1.for the jaxrs:server endpoint:







>>>>>         - servlet path mapping: '/services/*'







>>>>>                - jaxrs-server address attribute: address="/"







>>>>>                - @Path annotation: @Path("service1") 2.For the



>>>>> jaxws







>>>>> service endpoint:







>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS







>>>>> requests are handleb by the same CXF servle)







>>>>>                - jaxws:endpoint server address attribute:







>>>>> address="/service2"







>>>>>                - @WebService(name="service2") A correct request

>>>>> for







>>>>> '1' would be '/basePath>/services/service1/<ID>'.







>>>>> A correct request for '2' would be '/basePath>/services/service2'.







>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:







>>>>>         - the server address attribute







>>>>>         - The API annotation (@Path or @Webservice) The JAXWS



>>>>> server







>>>>> address attribute doesn't seem to interfere with the @Webservice







>>>>> annotation. While the jaxrs server address attribute does seem to







>>>>> interfere with the @Path annotation. I would have expected the



>>>>> jaxrs







>>>>> server aspects to be configured as:







>>>>>         - servlet path mapping: '/services/*'







>>>>>                - jaxrs-server address attribute: address="/service1"







>>>>>                - @Path annotation: @Path("service1") but then a







>>>>> valid







>>>>> request would be







>>>>>> /services/service1/service1/<ID>'.







>>>>> For both the 'address' attribute is relative to the servlet path.







>>>>> The @Path Javadoc mentions that this path is relative to the







>>>>> ApplicationPath which thus seems to be relative to the

>>>>> jaxrs-server







>>>>> address attribute. As for @Webservice it doesnn't seem to be







>>>>> url-path







>>> related.







>>>>> Question: Because now address="/" is set for the jaxrs:server will







>>>>> it







>>>>> also inspect requests targeted for the jaxws service as those







>>>>> requests have start with the same path '/<basePath>/services/...'.







>>>>> Albeit somewhat confusing.







>>>>> J.P.







>>>>> -----Original Message-----







>>>>> From: Andriy Redko <dr...@gmail.com>







>>>>> Sent: dinsdag 14 juni 2022 1:08







>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;







>>>>> issues@cxf.apache.org; dev@cxf.apache.org







>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi

>>>>> Jean,







>>>>> Indeed, the jaxrs:server does not expect address to be omitted,

>>>>> you







>>>>> could use the "/" (and I believe an empty string would also make it):







>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...







>>>>> </jaxrs:server>







>>>>> Thank you.







>>>>> Hope it helps.







>>>>> Best Regards,







>>>>>     Andriy Redko







>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean







>>>>>> declarations







>>>>>> like:







>>>>>>      <jaxrs:server id="restServer" basePackages="xxx">







>>>>>>            <jaxrs:serviceBeans>







>>>>>>                 <ref bean="TestApi" />







>>>>>>            </jaxrs:serviceBeans>







>>>>>>            <jaxrs:providers>







>>>>>>                 <…/>







>>>>>>            </jaxrs:providers>







>>>>>>            <jaxrs:features>







>>>>>>                 <… />







>>>>>>            </jaxrs:features>







>>>>>>            <jaxrs:inInterceptors>







>>>>>>                 <… />







>>>>>>            </jaxrs:inInterceptors>







>>>>>>            <jaxrs:outInterceptors>*







>>>>>>                 <**…**/>*







>>>>>>            </jaxrs:outInterceptors>*







>>>>>>      </jaxrs:server>











>>>>>> Here my “TestApi” bean interface is declared like:







>>>>>>       @Path("accounts")







>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)







>>>>>>        @Produces(MediaType.*APPLICATION_JSON*)







>>>>>>        public interface TestApi {







>>>>>>          …







>>>>>>        }







>>>>>> And CXF is triggered via a servlet configuration like:







>>>>>>      <servlet>







>>>>>>              <display-name>CXF Servlet</display-name>







>>>>>>              <servlet-name>CXFServlet</servlet-name>







>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servl

>>>>>> e







>>>>>> t













>>>>>>        </servlet>







>>>>>>        <servlet-mapping>







>>>>>>              <servlet-name>CXFServlet</servlet-name>







>>>>>>              <url-pattern>/services/*</url-pattern>







>>>>>>        </servlet-mapping>











>>>>>> Because I’ve got the @Path declaration on the interface type I’ve







>>>>>> omitted







>>>>>> the address=”accounts” attribute on the jaxrs:server declaration







>>>>>> since otherwise







>>>>>> I noticed that the server would be listening to







>>>>>> /basepath/services/ accounts/accounts/…).







>>>>>> Now this configuration works perfectly, only when shutting down







>>>>>> the application server cxf calls







>>>>>>         ServerImpl#destroy()







>>>>>> which delegates (via Obeservable) to







>>>>>> AbstractHTTPDestination#deactivate()







>>>>>> which calls







>>>>>> registry.removeDestination(path).







>>>>>> This path is null (no ‘address’ specified on jaxrs:server







>>>>>> declaration) and results in a NPE on the registry Map.







>>>>>> This causes an unclean shutdown of my server.







>>>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?







>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration







>>>>>> correctly interact with the @Path parameter on the API interface?







>>> <<...>>

RE: How to setup multiple JAXRS server endpoints

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
Hi Andriy,



As a test I removed all JAX-RS endpoints that use Swagger v2 annotations
from my configuration file (see attachment).

So I've now only 1 JAX-RS endpoint, fully annotated with Swagger v3
annotations, using the OpenApiFeature i.o. Swagger2Feature.

If I run my server with this configuration I only get the (working) *WADL*
and *OpenAPI* endpoints, no Swagger UI endpoint:





So there is some configuration missing to detect/activate the Swagger
endpoint. When I look at the samples that come with the distribution of CXF
(I am using v3.5.6) nothing special seems to be configured to activate this?

Do you have any idea how the SwaggerUiService is picked up when loading?



J.P.



-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: dinsdag 11 juli 2023 3:44
To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
Subject: Re: How to setup multiple JAXRS server endpoints



Hi Jean,



I guess you figured one issue, swagger.json -> openapi.json, but to be
honest we have never tested or envisioned the application that would use
OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same time, I am afraid this is
just not supported. You may get things back on track when going with
OpenAPI 3.0 for all services.



Thank you.



Best Regards,

    Andriy Redko





> Hi Andriy,







> I am trying to trace the difference in handling with another

> application where I’ve got only one CXF service endpoint that uses

> swagger v3 openapi annotations.



> There I see that when handling the Swagger page request (

> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json) the

> JAXRSInInterceptor is calling:







> *JAXRSUtils.**getRootResources*(Message message)







> It contains 4 entries:



>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint

>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource

>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService















> On the application described below with the service ‘oidcsim’ when

> calling the swagger page request

> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the

> result of the getRootResources doesn’t contain the ClassResourceInfo ‘

> SwaggerUiService’. It only contains 3 entries:



>    - (twice) OidcProviderApiServiceImpl (my service endpoint)

>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource







> The SwaggerUiService is the one that is configured to handle the
‘api-docs’

> path-request. Since it is missing the request is tried to match with

> the other two resources but fails, hence ‘NOT FOUND’ exception.







> I can’t trace back where these rootResources are set and why the

> SwaggerUiService’ isn’t listed.







> J.P.



> *From:* Jean Pierre URKENS <je...@devoteam.com>

> *Sent:* maandag 10 juli 2023 13:43

> *To:* 'Andriy Redko' <dr...@gmail.com>

> *Subject:* RE: How to setup multiple JAXRS server endpoints







> Andriy,







> I am trying to switch from Swagger v2 to OpenApi v3 annotations

> basically because my starting point is an OpenApi v3.0.7 yaml file

> description and OpenAPI seems to be the way forward.



> For applications where I have only one CXF JAX-RS endpoint exposed I

> had no problems converting. However as soon as there are multiple

> endpoints I run into troubles.







> So, to recall, I've an application exposing 3 JAX-RS endpoints that

> where previously annotated with swagger v2 annotations (i.e. package

> io.swagger.annotations.*) which I migrated to



> swagger v3 annotations (package io.swagger.v3.oas.annotations.*). In

> accordance I altered my CXF JAX-RS endpoint configuration from (only

> showing relevant parts, see attachment for full setup):







>                <!-- CXF Swagger2Feature -->



>                <bean id="SwaggerUiConfigOidcApi"

> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>                               <property name="queryConfigEnabled"



>                               <property name="url"

> value="/op/services/oidcsim/swagger.yaml"/>



>                </bean>



>                <bean id="Swagger2FeatureOidcApi"

> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">



>                               <property name="basePath"

> value="/op/services/oidcsim"/>



>                               <property name="usePathBasedConfig"



>                               <property name="resourcePackage"

> value="be.dvtm.aeo.op.oidc"/>



>                               <property name="supportSwaggerUi"



>                               <property name="swaggerUiConfig"

> ref="SwaggerUiConfigOidcApi"/>



>                </bean>



>                <jaxrs:server id="OidcProviderApiServer"

> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>                               ....



>                               <jaxrs:features>



>                                              <ref

> bean="Swagger2FeatureOidcApi" />



>                               </jaxrs:features>



>                               ...



>                </jaxrs:server>







> TO:



>                <!-- CXF OpenAPIFeature -->



>                <bean id="OidcSwaggerUiConfig"

> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">



>                               <property name="queryConfigEnabled"



>                               <property name="url"

> value="openapi.json"/>



>                </bean>



>                <bean id="OidcOpenApiFeature"

> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">



>                               <property name="supportSwaggerUi"



>                               <property name="swaggerUiConfig"

> ref="OidcSwaggerUiConfig"/>



>                               <property name="swaggerUiVersion"



>                               <property name="scan" value="false"/>



>                               <property name="useContextBasedConfig"



>                               <property name="resourcePackages"

> value="be.dvtm.aeo.op.oidc"/>



>                </bean>



>                <jaxrs:server id="OidcProviderApiServer"

> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">



>                               ....



>                               <jaxrs:features>



>                                              <ref
bean="OidcOpenApiFeature"



>                               </jaxrs:features>



>                               ...



>                </jaxrs:server>











> Now when starting my application and navigating to the root part "

> http://localhost:localPort/op/services" I get an overview of all my

> endpoints:







> Now there are 3 RESTful service endpoints setup:



>    1. ‘oidcsim’ which I switched to swagger v3 annotations

>    2. ‘openapi’ currently still swagger v2 annotations

>    3. ‘sdx’ currently still swagger v2 annotations







> all endpoints work except for the ‘swagger endpoint address for the

> oidcsim

> endpoint:

> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services/oi

> dcsim/swagger.json



> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger*

> endpoint of the oidcsim resource. I am getting an error (the value of

> the ‘url’ query parameter isn’t relevant):







>         “WebApplicationException has been caught, status: 404,

> message: HTTP 404 Not Found”







> When I try (without the ‘/oidcsim’ context):

> http://l-p53-008:8081/op/services/api-docs I get:



>                “No service was found.”







> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs

> doesn’t exist, where as the endpoint

> http://l-p53-008:8081/op/services/api-docs does exist but no service
description is found?



> Of course my intention is to get working, as previously with the

> swagger v2 setup for which I then specifically added the

> *Swagger2Feature* config

> parameters:



>                               <property name="basePath"

> value="/op/services/oidcsim"/>



>                               <property name="usePathBasedConfig"







> But I don’t find the according configuration options for the

> *OpenApiFeature* class or whether I should configure this in another way.







> Any suggestions on this?







> Regards,







> J.P.











> -----Original Message-----

> From: Andriy Redko <dr...@gmail.com>

> Sent: donderdag 25 mei 2023 2:27

> To: Jean Pierre URKENS <je...@devoteam.com>;

> dev@cxf.apache.org

> Subject: Re: How to setup multiple JAXRS server endpoints







> Hi Jean,







> You may run into Swagger JAX-RS scanner limitations, as far as I can

> tell - it checks class annotations for SwaggerDefinition, does not

> traverse the hierarchy [1].







> [1]

> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-j

> axrs/src/main/java/io/swagger/jaxrs/Reader.java#L194







> Best Regards,



>     Andriy Redko







>>  RE: How to setup multiple JAXRS server endpoints







>> Still one question );







>> The generated swagger file doesn’t take into account the



>> @SwaggerDefintion on my interface classes?







>> As a test I looked at



>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma



>> in/release/samples/jax_rs/description_swagger2_web**



>> and** modified** sample2*



>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma



>> in/release/samples/jax_rs/description_swagger2_web



>> and modified sample2> as follows:







>>    @Path("/sample2")







>>       @Api(value = "/sample2",authorizations=



>>       {@Authorization(value="bearer")},description = "Sample2

> (modified) JAX-RS



>>       service with Swagger documentation")







>>       @SwaggerDefinition(







>>               info = @Info(







>>                       description = "Sample2 server",







>>                       version="1.0",







>>                       title = "Test2",







>>                       contact = @Contact(name = "J.P. Urkens",email = "



>>       *jean-pierre.urkens@devoteam.com* <

> jean-pierre.urkens@devoteam.com>



>>       ")),







>>               securityDefinition =



>>       @SecurityDefinition(apiKeyAuthDefinitions=



> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="Au

> thorization",description="Use*



>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer



>>       &lt;accessToken&gt;'")})







>>       )







>>       public class Sample2 {...}







>> This correctly generates the ‘securityDefintions’ in the swagger file.







>> If include the same @SwaggerDefinition and the authorizations on



>> the @Api annotation as above in my interface classes then the



>> generated swagger file doesn’t contain the ‘securityDefintions’ ?







>> Any idea what I might be missing?







>> Regards,







>> J.P.







>> -----Original Message-----



>> From: Jean Pierre URKENS <je...@devoteam.com>



>> Sent: dinsdag 23 mei 2023 12:52



>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <





>> Subject: RE: How to setup multiple JAXRS server endpoints







>> Hi Andriy,







>> I added the parameter usePathBasedConfig=true to the



>> Swagger2Feature bean declarations but still it does generate an



>> empty swagger.yaml for interfaces KmopResources and



>> KmopDienstverlener although I noticed that for these interfaces the



>> @Path() annotation was commented out (as I included it in the



>> server declaration). After providing an empty @Path("") declaration

>> on

> the API interface classes everything worked.







>> Thanks for the support.







>> -----Original Message-----







>> From: Andriy Redko <dr...@gmail.com>







>> Sent: dinsdag 23 mei 2023 3:42







>> To: Jean Pierre URKENS <je...@devoteam.com>;



>> dev@cxf.apache.org







>> Subject: Re: How to setup multiple JAXRS server endpoints







>> Hi Jean,







>> The main problem to configure Swagger property in your particular



>> case is that the server address is not "known" or "introspectable"

>> for

> Swagger.



>> Intuitively, it has to be set manually using basePath to the,



>> essentially, the server address







>> part:







>>  - /op/services/accounts







>>  - /op/services/resources







>>  - /op/services/dienstverlener







>> You could read more about other Swagger properties you have asked here:



>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte



>> gration-and-Configuration#configuration-properties







>> You definitely need to set usePathBasedConfig to "true" otherwise



>> you will see the same Swagger specs for all servers. We have a



>> sample here which uses 2 jaxrs:server







>> instances:



>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai



>> n/release/samples/jax_rs/description_swagger2_web







>> Regarding SwaggerUI, I think the value for each of those should be



>> set to,



>> respectively:







>>  - /op/services/accounts/swagger.yaml







>>  - /op/services/resources/swagger.yaml







>>  - /op/services/dienstverlener/swagger.yaml







>> I believe this is matching your settings already, except the



>> usePathBasedConfig part. The example referred above could be



>> helpful, my apologies if I missed something, there are quite a lot



>> of questions :-) The fact that the generated Swagger specification



>> is empty is unexpected - it should not happen when JAX-RS resources

> are properly configured.







>> Thank you.







>> Best Regards,







>>     Andriy Redko







>>>  RE: How to setup multiple JAXRS server endpoints







>>> Hi Andriy,







>>> I am not quite understanding how to correctly configure the



>> Swagger2Feature.







>>> Referring to the attached cxf-endpoints configuration I (as a



>>> test)







>>> created







>>> 3 JAXRS server instances:







>>> 1.      A* KmopApiServer* server for the*







>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving







>>> requests for URI path:







>>>        * <protocol>**//<host:<port>/op/services/accounts*







>>>    ‘op’  = root path of the web application







>>>             ‘services’ = servlet path of the CXF-servlet







>>>       The address of the server is set to ‘/accounts’ and the



>>> @Path(…)







>>>       annotation on the interface class was cleared.







>>> 2.      A* Kmop**Resources**ApiServer* server for the*

> be.dvtm.aeo.op.*







>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving







>>> requests for URI path:







>>>        * <protocol>**//<host:<port>/op/services/**resources*







>>> The address of the server is set to ‘/resources’ and the @Path(…)







>>> annotation on the interface class was cleared.







>>> 3.      A* Kmop**Dienstverlener**Server* server for the*



>> be.dvtm.aeo.op.*







>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving







>>> requests for URI path:







>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*







>>> The address of the server is set to ‘/dienstverlener’ and the







>>> @Path(…) annotation on the interface class was cleared.







>>> For each of these server instances I’ve set the Swagger2Feature







>>> with configuration as indicated in the attached cxf-endpoints.xml.







>>> With regard to the configurations for the Swagger2Feature I’ve the







>>> following questions:







>>> a)      Referring to *

> https://cxf.apache.org/docs/swagger2feature.html*







>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you







>>> clarify on the following configuration parameters:







>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘







>>> /op/services’) or to the JAX-RS server instance (e.g.







>>> ‘/op/services/accounts’) or still something else? Is it used to







>>> resolve service classes or is it just for documentation in the



>>> swagger



>> file?







>>> *ii.    ** resourcePackage* – the description mentions ‘package names’







>>> while the default mentions ‘service classes’? Service 2 and 3



>>> above







>>> are within the same package (generated from the same yaml







>>> specification that included both interfaces).







>>> *iii.   ** ig**noreRoutes* – is this taken into account when







>>> scanAllResources=false?







>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter

> value







>>> (cf. question ‘a’)?







>>> b)      What would be the correct URL to generate a swagger.yaml

>>> file



>> for







>>> each of the above interfaces? Initially I called:







>>> *i.     **



>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*







>>> *ii.    **



>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*







>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*







>>> *lener/swagger.yaml*







>>>    All three requests delivered the same yaml specification,



>>> namely



>> the one







>>>       for interface* KmopApiServer*?







>>> c)      I tried to debug the processing of the requests under ‘b)’

>>> and



>> this







>>> is done by the class JAXRSInterceptor#processRequest where the







>>> MessageImpl object for request “ii.” looks like the one attached.







>>> It finds 3 resource







>>> classes:







>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl







>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource







>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService







>>> è       It matches the request to resource*



>> Swagger2ApiListingResource* with







>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*







>>> process(…)* method.







>>> è       Here it seems to go wrong. It generates a

> SwaggerContextService







>>> having basePath=/op/services/resources/,swaggerConfig=null,







>>> usePathBasedConfig=null and then calls







>>> SwaggerContextService.getSwagger()







>>> which returns the Swagger definition for interface KmopApiServer?







>>> It looks like it caches generated swagger definitions based on a







>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the







>>> same for all 3 interfaces as usePathBasedConfig=null







>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is







>>> derived from the ServletConfig parameter







>>> ‘swagger.use.path.based.config’.* So should this be set on the







>>> declaration of the CXFServlet** in web.xml?*







>>> è       Actually the SwaggerConfig, the JaxrsScanner and the

>>> generated



>> Swagger







>>> are cached using keys like







>>> ‘swagger.config.id.[default|baseUriPath]’, ‘







>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’



>> is only done when usePathBasedconfig=true.







>>> è       If I patch this to true then configIdKey=’







>>> swagger.config.id./op/services/resources/’ and no swagger entry is







>>> cached for this key so it will generate a new one. Again by







>>> patching







>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru



>>> e







>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”







>>> è       Again Scanners are cached and if usePathBasedConfig=null it



>> will use







>>> the one cached under  ‘swagger.scanner.id.default’ and this again







>>> returns the swagger definition for the KmopApiService interface.







>>> è       So patching usePathBasedConfig=true will return a new one







>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner







>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘







>>> which is correct. It will generate a new (but empty) Swagger object.







>>> è       Next Swagger2ApiListingResource will call the







>>> customizer.customize(s), which still isn’t putting anything new in







>>> the Swagger object. Should it or should the next step do this?







>>> è       Next BaseApiListingResource#getListing(…) is called which on



>> its







>>> turn calls getListingYamlResponse(..)







>>> è       The final result is a swagger.yaml document with following



>> content:







>>>    swagger: "2.0"







>>>       info:







>>>         license:







>>>           name: "Apache 2.0 License"







>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html







>>>       basePath: "/op/services/resources"







>>>        So basically an empty swagger file.







>>> d)      The usePathBasedConfig is derived from the ServletConfig



>> parameter ‘







>>> swagger.use.path.based.config’. Without this parameter set to true







>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger







>>> object.* So should this be set on the declaration of the







>>> CXFServlet** in web.xml?*







>>> The majority in this processing happens in the library







>>> swagger-jaxrs-v1.6.10 which is included as a dependency on



>> cxf-rt-rs-service-description-swagger.







>>> Even if I patch usePathBasedConfig=true about everywhere where I







>>> met this it still doesn’t generate a correct swagger.yaml. Am I







>>> still missing some configuration parameter?







>>> Any suggestions on how to resolve this would be welcome.







>>> Regards,







>>> J.P. Urkens











































>>> <<...>> <<...>>







>>> -----Original Message-----







>>> From: Andriy Redko <dr...@gmail.com>







>>> Sent: maandag 8 mei 2023 23:15







>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev







>>> List <













>>> Subject: Re: How to setup multiple JAXRS server endpoints







>>> Hi Jean,







>>> Indeed the way you would like to do that is somewhat tricky.







>>>> So I tried to keep the @Path declaration on the interface classes



>>>> but







>>> changed them to @Path(“”). That does seems to work except the







>>> swagger stuff no longer correctly works.







>>> This is one of the possible options but OpenAPI/Swagger gets







>>> confused for a







>>> reason: the path is now implicit (not in the spec).







>>> So how about this option:







>>>  - use only one JAX-RS server (address "/")







>>>  - host both resources but use @Path("accounts") and







>>> @Path("resources") on them respectively











>>> I see that for @Path("accounts") you need to apply the







>>> "kmopApiAuthorizationFilter", that could be done using







>>> DynamicFeature [1], [2]. If this is not the option and you would







>>> prefer to use 2 separate JAX-RS servers, you may need to provide







>>> your own instance of Swagger2Customizer [3], [4] which allows to







>>> transform the OpenAPI/Swagger on the fly. Please let me know if



>>> that



>> would it work for you, thank you.







>>> [1]







>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic



>>> F







>>> eature.html







>>> [2]







>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born



>>> -







>>> equal.html







>>> [3]







>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger



>>> /







>>> Swagger2Customizer.html







>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has







>>> customizer







>>> property)











>>> Best Regards,







>>>     Andriy Redko







>>>> Hi Andriy,







>>>> I am again getting into trouble with server endpoint declarations.







>>>> Now







>>> because I am adding additional JAX-RS endpoints.







>>>> The issue is with:







>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration

>>>> in







>>> combination with







>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the

>>>> web.xml







>>> in combination with







>>>> 3.      The @Path declaration in the interface class in combination

>>>> with







>>>> 4.      The @Path declaration on the interface method in

>>>> combination

> with







>>>> So what I had is that my web application deployed under baseUlr 'op'







>>>> had







>>> one JAXRS server endpoint with declarations like:







>>>> 1.      <jaxrs:server id="restServer"







>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">







>>>> 2.      <url-pattern>/services/*</url-pattern>







>>>> 3.      @Path("accounts") on the public interface class







>>>> 4.      @Path("/{authorisationId}/customerFund") on the

>>>> customerFund







>>> interface method







>>>> A valid API call would thus be e.g.:







>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/cu

>>>> s



>>>> t







>>>> o







>>>> merFund







>>>> And this works correctly.







>>>> We're now introducing additional JAX-RS service endpoints and now I







>>>> am







>>> running into problems. This second endpoint was declared with:







>>>> 1.      <jaxrs:server id="resourceServer"







>>> basePackages="be.dvtm.aeo.op.resources" address="/">







>>>> 2.      <url-pattern>/services/*</url-pattern>







>>>> 3.      @Path("resources") on the public interface class







>>>> 4.      @Path("/NACE") on the NACE interface method







>>>> So here a valid API call woud be:







>>> https://<hostname>:<port>/op/services/resources/NACE.







>>>> The problem is that I can not declare two <jaxrs:server> entries



>>>> with







>>>> the







>>> same ‘address’ as it throws the exception:







>>>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:







>>> There is an endpoint already running on /.







>>>>  So I tried changing the addresses to:







>>>> ·       address=”accounts” for the restServer







>>>> ·       address=”resources” for the resourceServer







>>>> But to keep the API-call URLs the same I removed the @Path







>>>> declaration on







>>> the interface classes. By doing so the <jaxrs:server> bean







>>> declarations no longer loads successfully.







>>>> So I tried to keep the @Path declaration on the interface classes



>>>> but







>>> changed them to @Path(“”). That does seems to work except the







>>> swagger stuff no longer correctly works.







>>>> So what is the decent way to setup multiple JAX-RS server endpoints







>>>> where







>>> each server has its own configuration regarding supported features:







>>>> ·       own validation







>>>> ·       own object and exception mappings







>>>> ·       own swagger file generation







>>>> ·       own logging (in separate file if possible)







>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in







>>>> cooperation







>>> with swager-ui v4.5.0.







>>>> Below the declarations of my endpoints <<...>> Thanks for any advice.







>>>> Regards,







>>>> J.P. Urkens







>>>> -----Original Message-----







>>>> From: Andriy Redko <dr...@gmail.com>







>>>> Sent: zaterdag 18 juni 2022 1:12







>>>> To: Jean Pierre URKENS <je...@devoteam.com>;







>>>> issues@cxf.apache.org; dev@cxf.apache.org







>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,







>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'







>>>> Correct, so in the relative form like address="/<something>", the







>>>> JAX-RS







>>> endpoint path would be:







>>>>     <baseUrl>/<servlet path







mapping>>>>>/<address>/[@ApplicationPath]/[@Path]







>>>> The @ApplicationPath is optional in this case.







>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'







>>>> The JAX-WS is very different from JAX-RS, essentially the action







>>>> comes







>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/







>>> (@Path / @ApplicationPath are not relevant there).







>>>>> Question: Because now address="/" is set for the jaxrs:server will







>>>>> it







>>>>> also inspect requests targeted for the jaxws service as those







>>>>> requests have start with the same path '/<basePath>/services/...







>>>> This is a good question, I have not done it myself but I think it







>>>> should







>>> work:







>>>> the servlet dispatches according to registered services, in this







>>>> regard







>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?



>> Thank you.







>>>> Best Regards,







>>>>     Andriy Redko







>>>>> Hi Andriy,







>>>>> Using address="/" seems to work but still I don't understand how



>>>>> the







>>>>> following work together:







>>>>>  - path specification in servlet mapping for the CXF servlet







>>>>> (org.apache.cxf.transport.servlet.CXFServlet)







>>>>>  - the 'address' attribute on the jaxrs:server bean declaration







>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the







>>>>> service API description Say I've two services with (relateive to



>>>>> the







>>>>> host) url's:







>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'







>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'







>>>>> How do I configure above 3 aspects? Currently I have (working):







>>>>> 1.for the jaxrs:server endpoint:







>>>>>         - servlet path mapping: '/services/*'







>>>>>                - jaxrs-server address attribute: address="/"







>>>>>                - @Path annotation: @Path("service1") 2.For the



>>>>> jaxws







>>>>> service endpoint:







>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS







>>>>> requests are handleb by the same CXF servle)







>>>>>                - jaxws:endpoint server address attribute:







>>>>> address="/service2"







>>>>>                - @WebService(name="service2") A correct request

>>>>> for







>>>>> '1' would be '/basePath>/services/service1/<ID>'.







>>>>> A correct request for '2' would be '/basePath>/services/service2'.







>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:







>>>>>         - the server address attribute







>>>>>         - The API annotation (@Path or @Webservice) The JAXWS



>>>>> server







>>>>> address attribute doesn't seem to interfere with the @Webservice







>>>>> annotation. While the jaxrs server address attribute does seem to







>>>>> interfere with the @Path annotation. I would have expected the



>>>>> jaxrs







>>>>> server aspects to be configured as:







>>>>>         - servlet path mapping: '/services/*'







>>>>>                - jaxrs-server address attribute: address="/service1"







>>>>>                - @Path annotation: @Path("service1") but then a







>>>>> valid







>>>>> request would be







>>>>>> /services/service1/service1/<ID>'.







>>>>> For both the 'address' attribute is relative to the servlet path.







>>>>> The @Path Javadoc mentions that this path is relative to the







>>>>> ApplicationPath which thus seems to be relative to the

>>>>> jaxrs-server







>>>>> address attribute. As for @Webservice it doesnn't seem to be







>>>>> url-path







>>> related.







>>>>> Question: Because now address="/" is set for the jaxrs:server will







>>>>> it







>>>>> also inspect requests targeted for the jaxws service as those







>>>>> requests have start with the same path '/<basePath>/services/...'.







>>>>> Albeit somewhat confusing.







>>>>> J.P.







>>>>> -----Original Message-----







>>>>> From: Andriy Redko <dr...@gmail.com>







>>>>> Sent: dinsdag 14 juni 2022 1:08







>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;







>>>>> issues@cxf.apache.org; dev@cxf.apache.org







>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi

>>>>> Jean,







>>>>> Indeed, the jaxrs:server does not expect address to be omitted,

>>>>> you







>>>>> could use the "/" (and I believe an empty string would also make it):







>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...







>>>>> </jaxrs:server>







>>>>> Thank you.







>>>>> Hope it helps.







>>>>> Best Regards,







>>>>>     Andriy Redko







>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean







>>>>>> declarations







>>>>>> like:







>>>>>>      <jaxrs:server id="restServer" basePackages="xxx">







>>>>>>            <jaxrs:serviceBeans>







>>>>>>                 <ref bean="TestApi" />







>>>>>>            </jaxrs:serviceBeans>







>>>>>>            <jaxrs:providers>







>>>>>>                 <…/>







>>>>>>            </jaxrs:providers>







>>>>>>            <jaxrs:features>







>>>>>>                 <… />







>>>>>>            </jaxrs:features>







>>>>>>            <jaxrs:inInterceptors>







>>>>>>                 <… />







>>>>>>            </jaxrs:inInterceptors>







>>>>>>            <jaxrs:outInterceptors>*







>>>>>>                 <**…**/>*







>>>>>>            </jaxrs:outInterceptors>*







>>>>>>      </jaxrs:server>











>>>>>> Here my “TestApi” bean interface is declared like:







>>>>>>       @Path("accounts")







>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)







>>>>>>        @Produces(MediaType.*APPLICATION_JSON*)







>>>>>>        public interface TestApi {







>>>>>>          …







>>>>>>        }







>>>>>> And CXF is triggered via a servlet configuration like:







>>>>>>      <servlet>







>>>>>>              <display-name>CXF Servlet</display-name>







>>>>>>              <servlet-name>CXFServlet</servlet-name>







>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servl

>>>>>> e







>>>>>> t













>>>>>>        </servlet>







>>>>>>        <servlet-mapping>







>>>>>>              <servlet-name>CXFServlet</servlet-name>







>>>>>>              <url-pattern>/services/*</url-pattern>







>>>>>>        </servlet-mapping>











>>>>>> Because I’ve got the @Path declaration on the interface type I’ve







>>>>>> omitted







>>>>>> the address=”accounts” attribute on the jaxrs:server declaration







>>>>>> since otherwise







>>>>>> I noticed that the server would be listening to







>>>>>> /basepath/services/ accounts/accounts/…).







>>>>>> Now this configuration works perfectly, only when shutting down







>>>>>> the application server cxf calls







>>>>>>         ServerImpl#destroy()







>>>>>> which delegates (via Obeservable) to







>>>>>> AbstractHTTPDestination#deactivate()







>>>>>> which calls







>>>>>> registry.removeDestination(path).







>>>>>> This path is null (no ‘address’ specified on jaxrs:server







>>>>>> declaration) and results in a NPE on the registry Map.







>>>>>> This causes an unclean shutdown of my server.







>>>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?







>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration







>>>>>> correctly interact with the @Path parameter on the API interface?







>>> <<...>>

Re: How to setup multiple JAXRS server endpoints

Posted by Andriy Redko <dr...@gmail.com>.
Hi Jean,

I guess you figured one issue, swagger.json -> openapi.json, but to be honest we have never 
tested or envisioned the application that would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at 
the same time, I am afraid this is just not supported. You may get things back on track when 
going with OpenAPI 3.0 for all services. 

Thank you.

Best Regards,
    Andriy Redko


> Hi Andriy,



> I am trying to trace the difference in handling with another application
> where I’ve got only one CXF service endpoint that uses swagger v3 openapi
> annotations.

> There I see that when handling the Swagger page request (
> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json) the
> JAXRSInInterceptor is calling:



> *JAXRSUtils.**getRootResources*(Message message)



> It contains 4 entries:

>    - (twice) InkomOndernemingApiserviceImpl -> my service endpoint
>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource
>    - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService







> On the application described below with the service ‘oidcsim’ when calling
> the swagger page request
> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the result
> of the getRootResources doesn’t contain the ClassResourceInfo ‘
> SwaggerUiService’. It only contains 3 entries:

>    - (twice) OidcProviderApiServiceImpl (my service endpoint)
>    - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource



> The SwaggerUiService is the one that is configured to handle the ‘api-docs’
> path-request. Since it is missing the request is tried to match with the
> other two resources but fails, hence ‘NOT FOUND’ exception.



> I can’t trace back where these rootResources are set and why the
> SwaggerUiService’ isn’t listed.



> J.P.

> *From:* Jean Pierre URKENS <je...@devoteam.com>
> *Sent:* maandag 10 juli 2023 13:43
> *To:* 'Andriy Redko' <dr...@gmail.com>
> *Subject:* RE: How to setup multiple JAXRS server endpoints



> Andriy,



> I am trying to switch from Swagger v2 to OpenApi v3 annotations basically
> because my starting point is an OpenApi v3.0.7 yaml file description and
> OpenAPI seems to be the way forward.

> For applications where I have only one CXF JAX-RS endpoint exposed I had no
> problems converting. However as soon as there are multiple endpoints I run
> into troubles.



> So, to recall, I've an application exposing 3 JAX-RS endpoints that where
> previously annotated with swagger v2 annotations (i.e. package
> io.swagger.annotations.*) which I migrated to

> swagger v3 annotations (package io.swagger.v3.oas.annotations.*). In
> accordance I altered my CXF JAX-RS endpoint configuration from (only
> showing relevant parts, see attachment for full setup):



>                <!-- CXF Swagger2Feature -->

>                <bean id="SwaggerUiConfigOidcApi"
> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">

>                               <property name="queryConfigEnabled"

>                               <property name="url"
> value="/op/services/oidcsim/swagger.yaml"/>

>                </bean>

>                <bean id="Swagger2FeatureOidcApi"
> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">

>                               <property name="basePath"
> value="/op/services/oidcsim"/>

>                               <property name="usePathBasedConfig"

>                               <property name="resourcePackage"
> value="be.dvtm.aeo.op.oidc"/>

>                               <property name="supportSwaggerUi"

>                               <property name="swaggerUiConfig"
> ref="SwaggerUiConfigOidcApi"/>

>                </bean>

>                <jaxrs:server id="OidcProviderApiServer"
> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">

>                               ....

>                               <jaxrs:features>

>                                              <ref
> bean="Swagger2FeatureOidcApi" />

>                               </jaxrs:features>

>                               ...

>                </jaxrs:server>



> TO:

>                <!-- CXF OpenAPIFeature -->

>                <bean id="OidcSwaggerUiConfig"
> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">

>                               <property name="queryConfigEnabled"

>                               <property name="url" value="openapi.json"/>

>                </bean>

>                <bean id="OidcOpenApiFeature"
> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">

>                               <property name="supportSwaggerUi"

>                               <property name="swaggerUiConfig"
> ref="OidcSwaggerUiConfig"/>

>                               <property name="swaggerUiVersion"

>                               <property name="scan" value="false"/>

>                               <property name="useContextBasedConfig"

>                               <property name="resourcePackages"
> value="be.dvtm.aeo.op.oidc"/>

>                </bean>

>                <jaxrs:server id="OidcProviderApiServer"
> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">

>                               ....

>                               <jaxrs:features>

>                                              <ref bean="OidcOpenApiFeature"

>                               </jaxrs:features>

>                               ...

>                </jaxrs:server>





> Now when starting my application and navigating to the root part "
> http://localhost:localPort/op/services" I get an overview of all my
> endpoints:



> Now there are 3 RESTful service endpoints setup:

>    1. ‘oidcsim’ which I switched to swagger v3 annotations
>    2. ‘openapi’ currently still swagger v2 annotations
>    3. ‘sdx’ currently still swagger v2 annotations



> all endpoints work except for the ‘swagger endpoint address for the oidcsim
> endpoint:
> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services/oidcsim/swagger.json

> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger* endpoint of
> the oidcsim resource. I am getting an error (the value of the ‘url’ query
> parameter isn’t relevant):



>         “WebApplicationException has been caught, status: 404,
> message: HTTP 404 Not Found”



> When I try (without the ‘/oidcsim’ context):
> http://l-p53-008:8081/op/services/api-docs I get:

>                “No service was found.”



> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs doesn’t
> exist, where as the endpoint http://l-p53-008:8081/op/services/api-docs does
> exist but no service description is found?

> Of course my intention is to get working, as previously with the swagger v2
> setup for which I then specifically added the *Swagger2Feature* config
> parameters:

>                               <property name="basePath"
> value="/op/services/oidcsim"/>

>                               <property name="usePathBasedConfig"



> But I don’t find the according configuration options for the
> *OpenApiFeature* class or whether I should configure this in another way.



> Any suggestions on this?



> Regards,



> J.P.





> -----Original Message-----
> From: Andriy Redko <dr...@gmail.com>
> Sent: donderdag 25 mei 2023 2:27
> To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
> Subject: Re: How to setup multiple JAXRS server endpoints



> Hi Jean,



> You may run into Swagger JAX-RS scanner limitations, as far as I can tell -
> it checks class annotations for SwaggerDefinition, does not traverse the
> hierarchy [1].



> [1]
> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java#L194



> Best Regards,

>     Andriy Redko



>>  RE: How to setup multiple JAXRS server endpoints



>> Still one question );



>> The generated swagger file doesn’t take into account the

>> @SwaggerDefintion on my interface classes?



>> As a test I looked at

>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma

>> in/release/samples/jax_rs/description_swagger2_web**

>> and** modified** sample2*

>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma

>> in/release/samples/jax_rs/description_swagger2_web

>> and modified sample2> as follows:



>>    @Path("/sample2")



>>       @Api(value = "/sample2",authorizations=

>>       {@Authorization(value="bearer")},description = "Sample2
> (modified) JAX-RS

>>       service with Swagger documentation")



>>       @SwaggerDefinition(



>>               info = @Info(



>>                       description = "Sample2 server",



>>                       version="1.0",



>>                       title = "Test2",



>>                       contact = @Contact(name = "J.P. Urkens",email = "

>>       *jean-pierre.urkens@devoteam.com* <
> jean-pierre.urkens@devoteam.com>

>>       ")),



>>               securityDefinition =

>>       @SecurityDefinition(apiKeyAuthDefinitions=

> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="Authorization",description="Use*

>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer

>>       &lt;accessToken&gt;'")})



>>       )



>>       public class Sample2 {...}



>> This correctly generates the ‘securityDefintions’ in the swagger file.



>> If include the same @SwaggerDefinition and the authorizations on

>> the @Api annotation as above in my interface classes then the

>> generated swagger file doesn’t contain the ‘securityDefintions’ ?



>> Any idea what I might be missing?



>> Regards,



>> J.P.



>> -----Original Message-----

>> From: Jean Pierre URKENS <je...@devoteam.com>

>> Sent: dinsdag 23 mei 2023 12:52

>> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <


>> Subject: RE: How to setup multiple JAXRS server endpoints



>> Hi Andriy,



>> I added the parameter usePathBasedConfig=true to the

>> Swagger2Feature bean declarations but still it does generate an

>> empty swagger.yaml for interfaces KmopResources and

>> KmopDienstverlener although I noticed that for these interfaces the

>> @Path() annotation was commented out (as I included it in the

>> server declaration). After providing an empty @Path("") declaration on
> the API interface classes everything worked.



>> Thanks for the support.



>> -----Original Message-----



>> From: Andriy Redko <dr...@gmail.com>



>> Sent: dinsdag 23 mei 2023 3:42



>> To: Jean Pierre URKENS <je...@devoteam.com>;

>> dev@cxf.apache.org



>> Subject: Re: How to setup multiple JAXRS server endpoints



>> Hi Jean,



>> The main problem to configure Swagger property in your particular

>> case is that the server address is not "known" or "introspectable" for
> Swagger.

>> Intuitively, it has to be set manually using basePath to the,

>> essentially, the server address



>> part:



>>  - /op/services/accounts



>>  - /op/services/resources



>>  - /op/services/dienstverlener



>> You could read more about other Swagger properties you have asked here:

>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte

>> gration-and-Configuration#configuration-properties



>> You definitely need to set usePathBasedConfig to "true" otherwise

>> you will see the same Swagger specs for all servers. We have a

>> sample here which uses 2 jaxrs:server



>> instances:

>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai

>> n/release/samples/jax_rs/description_swagger2_web



>> Regarding SwaggerUI, I think the value for each of those should be

>> set to,

>> respectively:



>>  - /op/services/accounts/swagger.yaml



>>  - /op/services/resources/swagger.yaml



>>  - /op/services/dienstverlener/swagger.yaml



>> I believe this is matching your settings already, except the

>> usePathBasedConfig part. The example referred above could be

>> helpful, my apologies if I missed something, there are quite a lot

>> of questions :-) The fact that the generated Swagger specification

>> is empty is unexpected - it should not happen when JAX-RS resources
> are properly configured.



>> Thank you.



>> Best Regards,



>>     Andriy Redko



>>>  RE: How to setup multiple JAXRS server endpoints



>>> Hi Andriy,



>>> I am not quite understanding how to correctly configure the

>> Swagger2Feature.



>>> Referring to the attached cxf-endpoints configuration I (as a

>>> test)



>>> created



>>> 3 JAXRS server instances:



>>> 1.      A* KmopApiServer* server for the*



>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving



>>> requests for URI path:



>>>        * <protocol>**//<host:<port>/op/services/accounts*



>>>    ‘op’  = root path of the web application



>>>             ‘services’ = servlet path of the CXF-servlet



>>>       The address of the server is set to ‘/accounts’ and the

>>> @Path(…)



>>>       annotation on the interface class was cleared.



>>> 2.      A* Kmop**Resources**ApiServer* server for the*
> be.dvtm.aeo.op.*



>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving



>>> requests for URI path:



>>>        * <protocol>**//<host:<port>/op/services/**resources*



>>> The address of the server is set to ‘/resources’ and the @Path(…)



>>> annotation on the interface class was cleared.



>>> 3.      A* Kmop**Dienstverlener**Server* server for the*

>> be.dvtm.aeo.op.*



>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving



>>> requests for URI path:



>>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*



>>> The address of the server is set to ‘/dienstverlener’ and the



>>> @Path(…) annotation on the interface class was cleared.



>>> For each of these server instances I’ve set the Swagger2Feature



>>> with configuration as indicated in the attached cxf-endpoints.xml.



>>> With regard to the configurations for the Swagger2Feature I’ve the



>>> following questions:



>>> a)      Referring to *
> https://cxf.apache.org/docs/swagger2feature.html*



>>> <https://cxf.apache.org/docs/swagger2feature.html>  could you



>>> clarify on the following configuration parameters:



>>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘



>>> /op/services’) or to the JAX-RS server instance (e.g.



>>> ‘/op/services/accounts’) or still something else? Is it used to



>>> resolve service classes or is it just for documentation in the

>>> swagger

>> file?



>>> *ii.    ** resourcePackage* – the description mentions ‘package names’



>>> while the default mentions ‘service classes’? Service 2 and 3

>>> above



>>> are within the same package (generated from the same yaml



>>> specification that included both interfaces).



>>> *iii.   ** ig**noreRoutes* – is this taken into account when



>>> scanAllResources=false?



>>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter
> value



>>> (cf. question ‘a’)?



>>> b)      What would be the correct URL to generate a swagger.yaml file

>> for



>>> each of the above interfaces? Initially I called:



>>> *i.     **

>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*



>>> *ii.    **

>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*



>>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*



>>> *lener/swagger.yaml*



>>>    All three requests delivered the same yaml specification,

>>> namely

>> the one



>>>       for interface* KmopApiServer*?



>>> c)      I tried to debug the processing of the requests under ‘b)’ and

>> this



>>> is done by the class JAXRSInterceptor#processRequest where the



>>> MessageImpl object for request “ii.” looks like the one attached.



>>> It finds 3 resource



>>> classes:



>>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl



>>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource



>>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService



>>> è       It matches the request to resource*

>> Swagger2ApiListingResource* with



>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*



>>> process(…)* method.



>>> è       Here it seems to go wrong. It generates a
> SwaggerContextService



>>> having basePath=/op/services/resources/,swaggerConfig=null,



>>> usePathBasedConfig=null and then calls



>>> SwaggerContextService.getSwagger()



>>> which returns the Swagger definition for interface KmopApiServer?



>>> It looks like it caches generated swagger definitions based on a



>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the



>>> same for all 3 interfaces as usePathBasedConfig=null



>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is



>>> derived from the ServletConfig parameter



>>> ‘swagger.use.path.based.config’.* So should this be set on the



>>> declaration of the CXFServlet** in web.xml?*



>>> è       Actually the SwaggerConfig, the JaxrsScanner and the generated

>> Swagger



>>> are cached using keys like



>>> ‘swagger.config.id.[default|baseUriPath]’, ‘



>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’

>> is only done when usePathBasedconfig=true.



>>> è       If I patch this to true then configIdKey=’



>>> swagger.config.id./op/services/resources/’ and no swagger entry is



>>> cached for this key so it will generate a new one. Again by



>>> patching



>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru

>>> e



>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”



>>> è       Again Scanners are cached and if usePathBasedConfig=null it

>> will use



>>> the one cached under  ‘swagger.scanner.id.default’ and this again



>>> returns the swagger definition for the KmopApiService interface.



>>> è       So patching usePathBasedConfig=true will return a new one



>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner



>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘



>>> which is correct. It will generate a new (but empty) Swagger object.



>>> è       Next Swagger2ApiListingResource will call the



>>> customizer.customize(s), which still isn’t putting anything new in



>>> the Swagger object. Should it or should the next step do this?



>>> è       Next BaseApiListingResource#getListing(…) is called which on

>> its



>>> turn calls getListingYamlResponse(..)



>>> è       The final result is a swagger.yaml document with following

>> content:



>>>    swagger: "2.0"



>>>       info:



>>>         license:



>>>           name: "Apache 2.0 License"



>>>           url: http://www.apache.org/licenses/LICENSE-2.0.html



>>>       basePath: "/op/services/resources"



>>>        So basically an empty swagger file.



>>> d)      The usePathBasedConfig is derived from the ServletConfig

>> parameter ‘



>>> swagger.use.path.based.config’. Without this parameter set to true



>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger



>>> object.* So should this be set on the declaration of the



>>> CXFServlet** in web.xml?*



>>> The majority in this processing happens in the library



>>> swagger-jaxrs-v1.6.10 which is included as a dependency on

>> cxf-rt-rs-service-description-swagger.



>>> Even if I patch usePathBasedConfig=true about everywhere where I



>>> met this it still doesn’t generate a correct swagger.yaml. Am I



>>> still missing some configuration parameter?



>>> Any suggestions on how to resolve this would be welcome.



>>> Regards,



>>> J.P. Urkens





















>>> <<...>> <<...>>



>>> -----Original Message-----



>>> From: Andriy Redko <dr...@gmail.com>



>>> Sent: maandag 8 mei 2023 23:15



>>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev



>>> List <






>>> Subject: Re: How to setup multiple JAXRS server endpoints



>>> Hi Jean,



>>> Indeed the way you would like to do that is somewhat tricky.



>>>> So I tried to keep the @Path declaration on the interface classes

>>>> but



>>> changed them to @Path(“”). That does seems to work except the



>>> swagger stuff no longer correctly works.



>>> This is one of the possible options but OpenAPI/Swagger gets



>>> confused for a



>>> reason: the path is now implicit (not in the spec).



>>> So how about this option:



>>>  - use only one JAX-RS server (address "/")



>>>  - host both resources but use @Path("accounts") and



>>> @Path("resources") on them respectively





>>> I see that for @Path("accounts") you need to apply the



>>> "kmopApiAuthorizationFilter", that could be done using



>>> DynamicFeature [1], [2]. If this is not the option and you would



>>> prefer to use 2 separate JAX-RS servers, you may need to provide



>>> your own instance of Swagger2Customizer [3], [4] which allows to



>>> transform the OpenAPI/Swagger on the fly. Please let me know if

>>> that

>> would it work for you, thank you.



>>> [1]



>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic

>>> F



>>> eature.html



>>> [2]



>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born

>>> -



>>> equal.html



>>> [3]



>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger

>>> /



>>> Swagger2Customizer.html



>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has



>>> customizer



>>> property)





>>> Best Regards,



>>>     Andriy Redko



>>>> Hi Andriy,



>>>> I am again getting into trouble with server endpoint declarations.



>>>> Now



>>> because I am adding additional JAX-RS endpoints.



>>>> The issue is with:



>>>> 1.      The 'address' attribute on the <jaxrs:server> declaration in



>>> combination with



>>>> 2.      The 'url-pattern' for the CXFServlet declaration in the web.xml



>>> in combination with



>>>> 3.      The @Path declaration in the interface class in combination with



>>>> 4.      The @Path declaration on the interface method in combination
> with



>>>> So what I had is that my web application deployed under baseUlr 'op'



>>>> had



>>> one JAXRS server endpoint with declarations like:



>>>> 1.      <jaxrs:server id="restServer"



>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">



>>>> 2.      <url-pattern>/services/*</url-pattern>



>>>> 3.      @Path("accounts") on the public interface class



>>>> 4.      @Path("/{authorisationId}/customerFund") on the customerFund



>>> interface method



>>>> A valid API call would thus be e.g.:



>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/cus

>>>> t



>>>> o



>>>> merFund



>>>> And this works correctly.



>>>> We're now introducing additional JAX-RS service endpoints and now I



>>>> am



>>> running into problems. This second endpoint was declared with:



>>>> 1.      <jaxrs:server id="resourceServer"



>>> basePackages="be.dvtm.aeo.op.resources" address="/">



>>>> 2.      <url-pattern>/services/*</url-pattern>



>>>> 3.      @Path("resources") on the public interface class



>>>> 4.      @Path("/NACE") on the NACE interface method



>>>> So here a valid API call woud be:



>>> https://<hostname>:<port>/op/services/resources/NACE.



>>>> The problem is that I can not declare two <jaxrs:server> entries

>>>> with



>>>> the



>>> same ‘address’ as it throws the exception:



>>>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:



>>> There is an endpoint already running on /.



>>>>  So I tried changing the addresses to:



>>>> ·       address=”accounts” for the restServer



>>>> ·       address=”resources” for the resourceServer



>>>> But to keep the API-call URLs the same I removed the @Path



>>>> declaration on



>>> the interface classes. By doing so the <jaxrs:server> bean



>>> declarations no longer loads successfully.



>>>> So I tried to keep the @Path declaration on the interface classes

>>>> but



>>> changed them to @Path(“”). That does seems to work except the



>>> swagger stuff no longer correctly works.



>>>> So what is the decent way to setup multiple JAX-RS server endpoints



>>>> where



>>> each server has its own configuration regarding supported features:



>>>> ·       own validation



>>>> ·       own object and exception mappings



>>>> ·       own swagger file generation



>>>> ·       own logging (in separate file if possible)



>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in



>>>> cooperation



>>> with swager-ui v4.5.0.



>>>> Below the declarations of my endpoints <<...>> Thanks for any advice.



>>>> Regards,



>>>> J.P. Urkens



>>>> -----Original Message-----



>>>> From: Andriy Redko <dr...@gmail.com>



>>>> Sent: zaterdag 18 juni 2022 1:12



>>>> To: Jean Pierre URKENS <je...@devoteam.com>;



>>>> issues@cxf.apache.org; dev@cxf.apache.org



>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,



>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'



>>>> Correct, so in the relative form like address="/<something>", the



>>>> JAX-RS



>>> endpoint path would be:



>>>>     <baseUrl>/<servlet path



mapping>>>>>/<address>/[@ApplicationPath]/[@Path]



>>>> The @ApplicationPath is optional in this case.



>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'



>>>> The JAX-WS is very different from JAX-RS, essentially the action



>>>> comes



>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/



>>> (@Path / @ApplicationPath are not relevant there).



>>>>> Question: Because now address="/" is set for the jaxrs:server will



>>>>> it



>>>>> also inspect requests targeted for the jaxws service as those



>>>>> requests have start with the same path '/<basePath>/services/...



>>>> This is a good question, I have not done it myself but I think it



>>>> should



>>> work:



>>>> the servlet dispatches according to registered services, in this



>>>> regard



>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?

>> Thank you.



>>>> Best Regards,



>>>>     Andriy Redko



>>>>> Hi Andriy,



>>>>> Using address="/" seems to work but still I don't understand how

>>>>> the



>>>>> following work together:



>>>>>  - path specification in servlet mapping for the CXF servlet



>>>>> (org.apache.cxf.transport.servlet.CXFServlet)



>>>>>  - the 'address' attribute on the jaxrs:server bean declaration



>>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the



>>>>> service API description Say I've two services with (relateive to

>>>>> the



>>>>> host) url's:



>>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'



>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'



>>>>> How do I configure above 3 aspects? Currently I have (working):



>>>>> 1.for the jaxrs:server endpoint:



>>>>>         - servlet path mapping: '/services/*'



>>>>>                - jaxrs-server address attribute: address="/"



>>>>>                - @Path annotation: @Path("service1") 2.For the

>>>>> jaxws



>>>>> service endpoint:



>>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS



>>>>> requests are handleb by the same CXF servle)



>>>>>                - jaxws:endpoint server address attribute:



>>>>> address="/service2"



>>>>>                - @WebService(name="service2") A correct request for



>>>>> '1' would be '/basePath>/services/service1/<ID>'.



>>>>> A correct request for '2' would be '/basePath>/services/service2'.



>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:



>>>>>         - the server address attribute



>>>>>         - The API annotation (@Path or @Webservice) The JAXWS

>>>>> server



>>>>> address attribute doesn't seem to interfere with the @Webservice



>>>>> annotation. While the jaxrs server address attribute does seem to



>>>>> interfere with the @Path annotation. I would have expected the

>>>>> jaxrs



>>>>> server aspects to be configured as:



>>>>>         - servlet path mapping: '/services/*'



>>>>>                - jaxrs-server address attribute: address="/service1"



>>>>>                - @Path annotation: @Path("service1") but then a



>>>>> valid



>>>>> request would be



>>>>>> /services/service1/service1/<ID>'.



>>>>> For both the 'address' attribute is relative to the servlet path.



>>>>> The @Path Javadoc mentions that this path is relative to the



>>>>> ApplicationPath which thus seems to be relative to the jaxrs-server



>>>>> address attribute. As for @Webservice it doesnn't seem to be



>>>>> url-path



>>> related.



>>>>> Question: Because now address="/" is set for the jaxrs:server will



>>>>> it



>>>>> also inspect requests targeted for the jaxws service as those



>>>>> requests have start with the same path '/<basePath>/services/...'.



>>>>> Albeit somewhat confusing.



>>>>> J.P.



>>>>> -----Original Message-----



>>>>> From: Andriy Redko <dr...@gmail.com>



>>>>> Sent: dinsdag 14 juni 2022 1:08



>>>>> To: Jean Pierre URKENS <je...@devoteam.com>;



>>>>> issues@cxf.apache.org; dev@cxf.apache.org



>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,



>>>>> Indeed, the jaxrs:server does not expect address to be omitted, you



>>>>> could use the "/" (and I believe an empty string would also make it):



>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...



>>>>> </jaxrs:server>



>>>>> Thank you.



>>>>> Hope it helps.



>>>>> Best Regards,



>>>>>     Andriy Redko



>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean



>>>>>> declarations



>>>>>> like:



>>>>>>      <jaxrs:server id="restServer" basePackages="xxx">



>>>>>>            <jaxrs:serviceBeans>



>>>>>>                 <ref bean="TestApi" />



>>>>>>            </jaxrs:serviceBeans>



>>>>>>            <jaxrs:providers>



>>>>>>                 <…/>



>>>>>>            </jaxrs:providers>



>>>>>>            <jaxrs:features>



>>>>>>                 <… />



>>>>>>            </jaxrs:features>



>>>>>>            <jaxrs:inInterceptors>



>>>>>>                 <… />



>>>>>>            </jaxrs:inInterceptors>



>>>>>>            <jaxrs:outInterceptors>*



>>>>>>                 <**…**/>*



>>>>>>            </jaxrs:outInterceptors>*



>>>>>>      </jaxrs:server>





>>>>>> Here my “TestApi” bean interface is declared like:



>>>>>>       @Path("accounts")



>>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)



>>>>>>        @Produces(MediaType.*APPLICATION_JSON*)



>>>>>>        public interface TestApi {



>>>>>>          …



>>>>>>        }



>>>>>> And CXF is triggered via a servlet configuration like:



>>>>>>      <servlet>



>>>>>>              <display-name>CXF Servlet</display-name>



>>>>>>              <servlet-name>CXFServlet</servlet-name>



>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servle



>>>>>> t






>>>>>>        </servlet>



>>>>>>        <servlet-mapping>



>>>>>>              <servlet-name>CXFServlet</servlet-name>



>>>>>>              <url-pattern>/services/*</url-pattern>



>>>>>>        </servlet-mapping>





>>>>>> Because I’ve got the @Path declaration on the interface type I’ve



>>>>>> omitted



>>>>>> the address=”accounts” attribute on the jaxrs:server declaration



>>>>>> since otherwise



>>>>>> I noticed that the server would be listening to



>>>>>> /basepath/services/ accounts/accounts/…).



>>>>>> Now this configuration works perfectly, only when shutting down



>>>>>> the application server cxf calls



>>>>>>         ServerImpl#destroy()



>>>>>> which delegates (via Obeservable) to



>>>>>> AbstractHTTPDestination#deactivate()



>>>>>> which calls



>>>>>> registry.removeDestination(path).



>>>>>> This path is null (no ‘address’ specified on jaxrs:server



>>>>>> declaration) and results in a NPE on the registry Map.



>>>>>> This causes an unclean shutdown of my server.



>>>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?



>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration



>>>>>> correctly interact with the @Path parameter on the API interface?



>>> <<...>>



Re: How to setup multiple JAXRS server endpoints

Posted by Andriy Redko <dr...@gmail.com>.
Hi Jean,

You may run into Swagger JAX-RS scanner limitations, as far as I can tell - it checks class annotations 
for SwaggerDefinition, does not traverse the hierarchy [1].

[1] https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java#L194

Best Regards,
    Andriy Redko

JPU>  RE: How to setup multiple JAXRS server endpoints

JPU> Still one question );

JPU> The generated swagger file doesn’t take into account the @SwaggerDefintion
JPU> on my interface classes?

JPU> As a test I looked at
JPU> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/main/release/samples/jax_rs/description_swagger2_web**
JPU> and** modified** sample2*
JPU> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/main/release/samples/jax_rs/description_swagger2_web
JPU> and modified sample2> as follows:

JPU>    @Path("/sample2")

JPU>       @Api(value = "/sample2",authorizations=
JPU>       {@Authorization(value="bearer")},description = "Sample2 (modified) JAX-RS
JPU>       service with Swagger documentation")

JPU>       @SwaggerDefinition(

JPU>               info = @Info(

JPU>                       description = "Sample2 server",

JPU>                       version="1.0",

JPU>                       title = "Test2",

JPU>                       contact = @Contact(name = "J.P. Urkens",email = "
JPU>       *jean-pierre.urkens@devoteam.com* <je...@devoteam.com>
JPU>       ")),

JPU>               securityDefinition =
JPU>       @SecurityDefinition(apiKeyAuthDefinitions=
JPU>       *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="Authorization",description="Use*
JPU>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer
JPU>       &lt;accessToken&gt;'")})

JPU>       )

JPU>       public class Sample2 {...}

JPU> This correctly generates the ‘securityDefintions’ in the swagger file.

JPU> If include the same @SwaggerDefinition and the authorizations on the @Api
JPU> annotation as above in my interface classes then the generated swagger
JPU> file doesn’t
JPU> contain the ‘securityDefintions’ ?

JPU> Any idea what I might be missing?

JPU> Regards,

JPU> J.P.

JPU> -----Original Message-----
JPU> From: Jean Pierre URKENS <je...@devoteam.com>
JPU> Sent: dinsdag 23 mei 2023 12:52
JPU> To: 'Andriy Redko' <dr...@gmail.com>; 'dev@cxf.apache.org' <
dev@cxf.apache.org>>
JPU> Subject: RE: How to setup multiple JAXRS server endpoints

JPU> Hi Andriy,

JPU> I added the parameter usePathBasedConfig=true to the Swagger2Feature bean
JPU> declarations but still it does generate an empty swagger.yaml for
JPU> interfaces KmopResources and KmopDienstverlener although I noticed that for
JPU> these interfaces the @Path() annotation was commented out (as I included it
JPU> in the server declaration). After providing an empty @Path("") declaration
JPU> on the API interface classes everything worked.

JPU> Thanks for the support.

JPU> -----Original Message-----

JPU> From: Andriy Redko <dr...@gmail.com>

JPU> Sent: dinsdag 23 mei 2023 3:42

JPU> To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org

JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

JPU> The main problem to configure Swagger property in your particular case is
JPU> that the server address is not "known" or "introspectable" for Swagger.
JPU> Intuitively, it has to be set manually using basePath to the, essentially,
JPU> the server address

JPU> part:

JPU>  - /op/services/accounts

JPU>  - /op/services/resources

JPU>  - /op/services/dienstverlener

JPU> You could read more about other Swagger properties you have asked here:
JPU> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties

JPU> You definitely need to set usePathBasedConfig to "true" otherwise you will
JPU> see the same Swagger specs for all servers. We have a sample here which
JPU> uses 2 jaxrs:server

JPU> instances:
JPU> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/main/release/samples/jax_rs/description_swagger2_web

JPU> Regarding SwaggerUI, I think the value for each of those should be set to,
JPU> respectively:

JPU>  - /op/services/accounts/swagger.yaml

JPU>  - /op/services/resources/swagger.yaml

JPU>  - /op/services/dienstverlener/swagger.yaml

JPU> I believe this is matching your settings already, except the
JPU> usePathBasedConfig part. The example referred above could be helpful, my
JPU> apologies if I missed something, there are quite a lot of questions :-) The
JPU> fact that the generated Swagger specification is empty is unexpected - it
JPU> should not happen when JAX-RS resources are properly configured.

JPU> Thank you.

JPU> Best Regards,

JPU>     Andriy Redko

JPU>>  RE: How to setup multiple JAXRS server endpoints

JPU>> Hi Andriy,

JPU>> I am not quite understanding how to correctly configure the
JPU> Swagger2Feature.

JPU>> Referring to the attached cxf-endpoints configuration I (as a test)

JPU>> created

JPU>> 3 JAXRS server instances:

JPU>> 1.      A* KmopApiServer* server for the*

JPU>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving

JPU>> requests for URI path:

JPU>>        * <protocol>**//<host:<port>/op/services/accounts*

JPU>>    ‘op’  = root path of the web application

JPU>>             ‘services’ = servlet path of the CXF-servlet

JPU>>       The address of the server is set to ‘/accounts’ and the @Path(…)

JPU>>       annotation on the interface class was cleared.

JPU>> 2.      A* Kmop**Resources**ApiServer* server for the* be.dvtm.aeo.op.*

JPU>> *openapi.**api.Kmop**Recources**ApiService* interface, serving

JPU>> requests for URI path:

JPU>>        * <protocol>**//<host:<port>/op/services/**resources*

JPU>> The address of the server is set to ‘/resources’ and the @Path(…)

JPU>> annotation on the interface class was cleared.

JPU>> 3.      A* Kmop**Dienstverlener**Server* server for the*
JPU> be.dvtm.aeo.op.*

JPU>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving

JPU>> requests for URI path:

JPU>>        * <protocol>**//<host:<port>/op/services/**dienstverlener*

JPU>> The address of the server is set to ‘/dienstverlener’ and the

JPU>> @Path(…) annotation on the interface class was cleared.

JPU>> For each of these server instances I’ve set the Swagger2Feature

JPU>> with configuration as indicated in the attached cxf-endpoints.xml.

JPU>> With regard to the configurations for the Swagger2Feature I’ve the

JPU>> following questions:

JPU>> a)      Referring to *https://cxf.apache.org/docs/swagger2feature.html*

JPU>> <https://cxf.apache.org/docs/swagger2feature.html>  could you

JPU>> clarify on the following configuration parameters:

JPU>> *i.     ** basePath* – Is this the path to the CXFServlet context (‘

JPU>> /op/services’) or to the JAX-RS server instance (e.g.

JPU>> ‘/op/services/accounts’) or still something else? Is it used to

JPU>> resolve service classes or is it just for documentation in the swagger
JPU> file?

JPU>> *ii.    ** resourcePackage* – the description mentions ‘package names’

JPU>> while the default mentions ‘service classes’? Service 2 and 3 above

JPU>> are within the same package (generated from the same yaml

JPU>> specification that included both interfaces).

JPU>> *iii.   ** ig**noreRoutes* – is this taken into account when

JPU>> scanAllResources=false?

JPU>> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter value

JPU>> (cf. question ‘a’)?

JPU>> b)      What would be the correct URL to generate a swagger.yaml file
JPU> for

JPU>> each of the above interfaces? Initially I called:

JPU>> *i.     **
JPU> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*

JPU>> *ii.    **
JPU> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*

JPU>> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*

JPU>> *lener/swagger.yaml*

JPU>>    All three requests delivered the same yaml specification, namely
JPU> the one

JPU>>       for interface* KmopApiServer*?

JPU>> c)      I tried to debug the processing of the requests under ‘b)’ and
JPU> this

JPU>> is done by the class JAXRSInterceptor#processRequest where the

JPU>> MessageImpl object for request “ii.” looks like the one attached.

JPU>> It finds 3 resource

JPU>> classes:

JPU>>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl

JPU>>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource

JPU>>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService

JPU>> è       It matches the request to resource*
JPU> Swagger2ApiListingResource* with

JPU>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*

JPU>> process(…)* method.

JPU>> è       Here it seems to go wrong. It generates a SwaggerContextService

JPU>> having basePath=/op/services/resources/,swaggerConfig=null,

JPU>> usePathBasedConfig=null and then calls

JPU>> SwaggerContextService.getSwagger()

JPU>> which returns the Swagger definition for interface KmopApiServer?

JPU>> It looks like it caches generated swagger definitions based on a

JPU>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the

JPU>> same for all 3 interfaces as usePathBasedConfig=null

JPU>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is

JPU>> derived from the ServletConfig parameter

JPU>> ‘swagger.use.path.based.config’.* So should this be set on the

JPU>> declaration of the CXFServlet** in web.xml?*

JPU>> è       Actually the SwaggerConfig, the JaxrsScanner and the generated
JPU> Swagger

JPU>> are cached using keys like

JPU>> ‘swagger.config.id.[default|baseUriPath]’, ‘

JPU>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’
JPU> is only done when usePathBasedconfig=true.

JPU>> è       If I patch this to true then configIdKey=’

JPU>> swagger.config.id./op/services/resources/’ and no swagger entry is

JPU>> cached for this key so it will generate a new one. Again by

JPU>> patching

JPU>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=true

JPU>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”

JPU>> è       Again Scanners are cached and if usePathBasedConfig=null it
JPU> will use

JPU>> the one cached under  ‘swagger.scanner.id.default’ and this again

JPU>> returns the swagger definition for the KmopApiService interface.

JPU>> è       So patching usePathBasedConfig=true will return a new one

JPU>> (DefaultJaxrsScanner). The classes to scan for in this new scanner

JPU>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘

JPU>> which is correct. It will generate a new (but empty) Swagger object.

JPU>> è       Next Swagger2ApiListingResource will call the

JPU>> customizer.customize(s), which still isn’t putting anything new in

JPU>> the Swagger object. Should it or should the next step do this?

JPU>> è       Next BaseApiListingResource#getListing(…) is called which on
JPU> its

JPU>> turn calls getListingYamlResponse(..)

JPU>> è       The final result is a swagger.yaml document with following
JPU> content:

JPU>>    swagger: "2.0"

JPU>>       info:

JPU>>         license:

JPU>>           name: "Apache 2.0 License"

JPU>>           url: http://www.apache.org/licenses/LICENSE-2.0.html

JPU>>       basePath: "/op/services/resources"

JPU>>        So basically an empty swagger file.

JPU>> d)      The usePathBasedConfig is derived from the ServletConfig
JPU> parameter ‘

JPU>> swagger.use.path.based.config’. Without this parameter set to true

JPU>> there will be only one Swaggerconfig, JaxrsScanner and Swagger

JPU>> object.* So should this be set on the declaration of the

JPU>> CXFServlet** in web.xml?*

JPU>> The majority in this processing happens in the library

JPU>> swagger-jaxrs-v1.6.10 which is included as a dependency on
JPU> cxf-rt-rs-service-description-swagger.

JPU>> Even if I patch usePathBasedConfig=true about everywhere where I

JPU>> met this it still doesn’t generate a correct swagger.yaml. Am I

JPU>> still missing some configuration parameter?

JPU>> Any suggestions on how to resolve this would be welcome.

JPU>> Regards,

JPU>> J.P. Urkens










JPU>> <<...>> <<...>>

JPU>> -----Original Message-----

JPU>> From: Andriy Redko <dr...@gmail.com>

JPU>> Sent: maandag 8 mei 2023 23:15

JPU>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev

JPU>> List <

dev@cxf.apache.org>>>

JPU>> Subject: Re: How to setup multiple JAXRS server endpoints

JPU>> Hi Jean,

JPU>> Indeed the way you would like to do that is somewhat tricky.

>>> So I tried to keep the @Path declaration on the interface classes but

JPU>> changed them to @Path(“”). That does seems to work except the

JPU>> swagger stuff no longer correctly works.

JPU>> This is one of the possible options but OpenAPI/Swagger gets

JPU>> confused for a

JPU>> reason: the path is now implicit (not in the spec).

JPU>> So how about this option:

JPU>>  - use only one JAX-RS server (address "/")

JPU>>  - host both resources but use @Path("accounts") and

JPU>> @Path("resources") on them respectively


JPU>> I see that for @Path("accounts") you need to apply the

JPU>> "kmopApiAuthorizationFilter", that could be done using

JPU>> DynamicFeature [1], [2]. If this is not the option and you would

JPU>> prefer to use 2 separate JAX-RS servers, you may need to provide

JPU>> your own instance of Swagger2Customizer [3], [4] which allows to

JPU>> transform the OpenAPI/Swagger on the fly. Please let me know if that
JPU> would it work for you, thank you.

JPU>> [1]

JPU>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/DynamicF

JPU>> eature.html

JPU>> [2]

JPU>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born-

JPU>> equal.html

JPU>> [3]

JPU>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger/

JPU>> Swagger2Customizer.html

JPU>> [4] https://cxf.apache.org/docs/swagger2feature.html (has

JPU>> customizer

JPU>> property)


JPU>> Best Regards,

JPU>>     Andriy Redko

>>> Hi Andriy,

>>> I am again getting into trouble with server endpoint declarations.

>>> Now

JPU>> because I am adding additional JAX-RS endpoints.

>>> The issue is with:

>>> 1.      The 'address' attribute on the <jaxrs:server> declaration in

JPU>> combination with

>>> 2.      The 'url-pattern' for the CXFServlet declaration in the web.xml

JPU>> in combination with

>>> 3.      The @Path declaration in the interface class in combination with

>>> 4.      The @Path declaration on the interface method in combination with

>>> So what I had is that my web application deployed under baseUlr 'op'

>>> had

JPU>> one JAXRS server endpoint with declarations like:

>>> 1.      <jaxrs:server id="restServer"

JPU>> basePackages="be.dvtm.aeo.op.sodexo" address="/">

>>> 2.      <url-pattern>/services/*</url-pattern>

>>> 3.      @Path("accounts") on the public interface class

>>> 4.      @Path("/{authorisationId}/customerFund") on the customerFund

JPU>> interface method

>>> A valid API call would thus be e.g.:

>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/cust

>>> o

>>> merFund

>>> And this works correctly.

>>> We're now introducing additional JAX-RS service endpoints and now I

>>> am

JPU>> running into problems. This second endpoint was declared with:

>>> 1.      <jaxrs:server id="resourceServer"

JPU>> basePackages="be.dvtm.aeo.op.resources" address="/">

>>> 2.      <url-pattern>/services/*</url-pattern>

>>> 3.      @Path("resources") on the public interface class

>>> 4.      @Path("/NACE") on the NACE interface method

>>> So here a valid API call woud be:

JPU>> https://<hostname>:<port>/op/services/resources/NACE.

>>> The problem is that I can not declare two <jaxrs:server> entries with

>>> the

JPU>> same ‘address’ as it throws the exception:

>>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:

JPU>> There is an endpoint already running on /.

>>>  So I tried changing the addresses to:

>>> ·       address=”accounts” for the restServer

>>> ·       address=”resources” for the resourceServer

>>> But to keep the API-call URLs the same I removed the @Path

>>> declaration on

JPU>> the interface classes. By doing so the <jaxrs:server> bean

JPU>> declarations no longer loads successfully.

>>> So I tried to keep the @Path declaration on the interface classes but

JPU>> changed them to @Path(“”). That does seems to work except the

JPU>> swagger stuff no longer correctly works.

>>> So what is the decent way to setup multiple JAX-RS server endpoints

>>> where

JPU>> each server has its own configuration regarding supported features:

>>> ·       own validation

>>> ·       own object and exception mappings

>>> ·       own swagger file generation

>>> ·       own logging (in separate file if possible)

>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in

>>> cooperation

JPU>> with swager-ui v4.5.0.

>>> Below the declarations of my endpoints <<...>> Thanks for any advice.

>>> Regards,

>>> J.P. Urkens

>>> -----Original Message-----

>>> From: Andriy Redko <dr...@gmail.com>

>>> Sent: zaterdag 18 juni 2022 1:12

>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>> issues@cxf.apache.org; dev@cxf.apache.org

>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,

>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'

>>> Correct, so in the relative form like address="/<something>", the

>>> JAX-RS

JPU>> endpoint path would be:

>>>     <baseUrl>/<servlet path

>>> mapping>/<address>/[@ApplicationPath]/[@Path]

>>> The @ApplicationPath is optional in this case.

>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'

>>> The JAX-WS is very different from JAX-RS, essentially the action

>>> comes

JPU>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/

JPU>> (@Path / @ApplicationPath are not relevant there).

>>>> Question: Because now address="/" is set for the jaxrs:server will

>>>> it

>>>> also inspect requests targeted for the jaxws service as those

>>>> requests have start with the same path '/<basePath>/services/...

>>> This is a good question, I have not done it myself but I think it

>>> should

JPU>> work:

>>> the servlet dispatches according to registered services, in this

>>> regard

JPU>> JAX-RS and JAX-WS should not conflict. Does it work in your case?
JPU> Thank you.

>>> Best Regards,

>>>     Andriy Redko

>>>> Hi Andriy,

>>>> Using address="/" seems to work but still I don't understand how the

>>>> following work together:

>>>>  - path specification in servlet mapping for the CXF servlet

>>>> (org.apache.cxf.transport.servlet.CXFServlet)

>>>>  - the 'address' attribute on the jaxrs:server bean declaration

>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the

>>>> service API description Say I've two services with (relateive to the

>>>> host) url's:

>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'

>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'

>>>> How do I configure above 3 aspects? Currently I have (working):

>>>> 1.for the jaxrs:server endpoint:

>>>>         - servlet path mapping: '/services/*'

>>>>                - jaxrs-server address attribute: address="/"

>>>>                - @Path annotation: @Path("service1") 2.For the jaxws

>>>> service endpoint:

>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS

>>>> requests are handleb by the same CXF servle)

>>>>                - jaxws:endpoint server address attribute:

>>>> address="/service2"

>>>>                - @WebService(name="service2") A correct request for

>>>> '1' would be '/basePath>/services/service1/<ID>'.

>>>> A correct request for '2' would be '/basePath>/services/service2'.

>>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:

>>>>         - the server address attribute

>>>>         - The API annotation (@Path or @Webservice) The JAXWS server

>>>> address attribute doesn't seem to interfere with the @Webservice

>>>> annotation. While the jaxrs server address attribute does seem to

>>>> interfere with the @Path annotation. I would have expected the jaxrs

>>>> server aspects to be configured as:

>>>>         - servlet path mapping: '/services/*'

>>>>                - jaxrs-server address attribute: address="/service1"

>>>>                - @Path annotation: @Path("service1") but then a

>>>> valid

>>>> request would be

>>>>> /services/service1/service1/<ID>'.

>>>> For both the 'address' attribute is relative to the servlet path.

>>>> The @Path Javadoc mentions that this path is relative to the

>>>> ApplicationPath which thus seems to be relative to the jaxrs-server

>>>> address attribute. As for @Webservice it doesnn't seem to be

>>>> url-path

JPU>> related.

>>>> Question: Because now address="/" is set for the jaxrs:server will

>>>> it

>>>> also inspect requests targeted for the jaxws service as those

>>>> requests have start with the same path '/<basePath>/services/...'.

>>>> Albeit somewhat confusing.

>>>> J.P.

>>>> -----Original Message-----

>>>> From: Andriy Redko <dr...@gmail.com>

>>>> Sent: dinsdag 14 juni 2022 1:08

>>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>>> issues@cxf.apache.org; dev@cxf.apache.org

>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,

>>>> Indeed, the jaxrs:server does not expect address to be omitted, you

>>>> could use the "/" (and I believe an empty string would also make it):

>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...

>>>> </jaxrs:server>

>>>> Thank you.

>>>> Hope it helps.

>>>> Best Regards,

>>>>     Andriy Redko

>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean

>>>>> declarations

>>>>> like:

>>>>>      <jaxrs:server id="restServer" basePackages="xxx">

>>>>>            <jaxrs:serviceBeans>

>>>>>                 <ref bean="TestApi" />

>>>>>            </jaxrs:serviceBeans>

>>>>>            <jaxrs:providers>

>>>>>                 <…/>

>>>>>            </jaxrs:providers>

>>>>>            <jaxrs:features>

>>>>>                 <… />

>>>>>            </jaxrs:features>

>>>>>            <jaxrs:inInterceptors>

>>>>>                 <… />

>>>>>            </jaxrs:inInterceptors>

>>>>>            <jaxrs:outInterceptors>*

>>>>>                 <**…**/>*

>>>>>            </jaxrs:outInterceptors>*

>>>>>      </jaxrs:server>


>>>>> Here my “TestApi” bean interface is declared like:

>>>>>       @Path("accounts")

>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)

>>>>>        @Produces(MediaType.*APPLICATION_JSON*)

>>>>>        public interface TestApi {

>>>>>          …

>>>>>        }

>>>>> And CXF is triggered via a servlet configuration like:

>>>>>      <servlet>

>>>>>              <display-name>CXF Servlet</display-name>

>>>>>              <servlet-name>CXFServlet</servlet-name>

>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servle

>>>>> t

-class>>>>>>

>>>>>        </servlet>

>>>>>        <servlet-mapping>

>>>>>              <servlet-name>CXFServlet</servlet-name>

>>>>>              <url-pattern>/services/*</url-pattern>

>>>>>        </servlet-mapping>


>>>>> Because I’ve got the @Path declaration on the interface type I’ve

>>>>> omitted

>>>>> the address=”accounts” attribute on the jaxrs:server declaration

>>>>> since otherwise

>>>>> I noticed that the server would be listening to

>>>>> /basepath/services/ accounts/accounts/…).

>>>>> Now this configuration works perfectly, only when shutting down

>>>>> the application server cxf calls

>>>>>         ServerImpl#destroy()

>>>>> which delegates (via Obeservable) to

>>>>> AbstractHTTPDestination#deactivate()

>>>>> which calls

>>>>> registry.removeDestination(path).

>>>>> This path is null (no ‘address’ specified on jaxrs:server

>>>>> declaration) and results in a NPE on the registry Map.

>>>>> This causes an unclean shutdown of my server.

>>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?

>>>>> How does the ‘address’ attribute on the jaxrs:server declaration

>>>>> correctly interact with the @Path parameter on the API interface?

JPU>> <<...>>


RE: How to setup multiple JAXRS server endpoints

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
Hi Andriy,

I added the parameter usePathBasedConfig=true to the Swagger2Feature bean
declarations but still it does generate an empty swagger.yaml for interfaces
KmopResources and KmopDienstverlener although I noticed that for these
interfaces the @Path() annotation was commented out (as I included it in the
server declaration). After providing an empty @Path("") declaration on the
API interface classes everything worked.

Thanks for the support.


-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: dinsdag 23 mei 2023 3:42
To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
Subject: Re: How to setup multiple JAXRS server endpoints

Hi Jean,

The main problem to configure Swagger property in your particular case is
that the server address is not "known" or "introspectable" for Swagger.
Intuitively, it has to be set manually using basePath to the, essentially,
the server address
part:

 - /op/services/accounts
 - /op/services/resources
 - /op/services/dienstverlener

You could read more about other Swagger properties you have asked here:
https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties

You definitely need to set usePathBasedConfig to "true" otherwise you will
see the same Swagger specs for all servers. We have a sample here which uses
2 jaxrs:server
instances:
https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/main/release/samples/jax_rs/description_swagger2_web

Regarding SwaggerUI, I think the value for each of those should be set to,
respectively:

 - /op/services/accounts/swagger.yaml
 - /op/services/resources/swagger.yaml
 - /op/services/dienstverlener/swagger.yaml

I believe this is matching your settings already, except the
usePathBasedConfig part. The example referred above could be helpful, my
apologies if I missed something, there are quite a lot of questions :-) The
fact that the generated Swagger specification is empty is unexpected - it
should not happen when JAX-RS resources are properly configured.

Thank you.

Best Regards,
    Andriy Redko

JPU>  RE: How to setup multiple JAXRS server endpoints

JPU> Hi Andriy,

JPU> I am not quite understanding how to correctly configure the
Swagger2Feature.

JPU> Referring to the attached cxf-endpoints configuration I (as a test)
JPU> created
JPU> 3 JAXRS server instances:

JPU> 1.      A* KmopApiServer* server for the*
JPU> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving
JPU> requests for URI path:
JPU>        * <protocol>**//<host:<port>/op/services/accounts*

JPU>    ‘op’  = root path of the web application

JPU>             ‘services’ = servlet path of the CXF-servlet

JPU>       The address of the server is set to ‘/accounts’ and the @Path(…)
JPU>       annotation on the interface class was cleared.

JPU> 2.      A* Kmop**Resources**ApiServer* server for the* be.dvtm.aeo.op.*
JPU> *openapi.**api.Kmop**Recources**ApiService* interface, serving
JPU> requests for URI path:
JPU>        * <protocol>**//<host:<port>/op/services/**resources*
JPU> The address of the server is set to ‘/resources’ and the @Path(…)
JPU> annotation on the interface class was cleared.

JPU> 3.      A* Kmop**Dienstverlener**Server* server for the*
be.dvtm.aeo.op.*
JPU> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving
JPU> requests for URI path:
JPU>        * <protocol>**//<host:<port>/op/services/**dienstverlener*
JPU> The address of the server is set to ‘/dienstverlener’ and the
JPU> @Path(…) annotation on the interface class was cleared.

JPU> For each of these server instances I’ve set the Swagger2Feature
JPU> with configuration as indicated in the attached cxf-endpoints.xml.

JPU> With regard to the configurations for the Swagger2Feature I’ve the
JPU> following questions:

JPU> a)      Referring to *https://cxf.apache.org/docs/swagger2feature.html*
JPU> <https://cxf.apache.org/docs/swagger2feature.html>  could you
JPU> clarify on the following configuration parameters:

JPU> *i.     ** basePath* – Is this the path to the CXFServlet context (‘
JPU> /op/services’) or to the JAX-RS server instance (e.g.
JPU> ‘/op/services/accounts’) or still something else? Is it used to
JPU> resolve service classes or is it just for documentation in the swagger
file?

JPU> *ii.    ** resourcePackage* – the description mentions ‘package names’
JPU> while the default mentions ‘service classes’? Service 2 and 3 above
JPU> are within the same package (generated from the same yaml
JPU> specification that included both interfaces).

JPU> *iii.   ** ig**noreRoutes* – is this taken into account when
JPU> scanAllResources=false?

JPU> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter value
JPU> (cf. question ‘a’)?

JPU> b)      What would be the correct URL to generate a swagger.yaml file
for
JPU> each of the above interfaces? Initially I called:

JPU> *i.     **
<protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*

JPU> *ii.    **
<protocol>**//<host:<port>/op/services/**resources/swagger.yaml*

JPU> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*
JPU> *lener/swagger.yaml*

JPU>    All three requests delivered the same yaml specification, namely the
one
JPU>       for interface* KmopApiServer*?

JPU> c)      I tried to debug the processing of the requests under ‘b)’ and
this
JPU> is done by the class JAXRSInterceptor#processRequest where the
JPU> MessageImpl object for request “ii.” looks like the one attached.
JPU> It finds 3 resource
JPU> classes:

JPU>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl

JPU>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource

JPU>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService

JPU> è       It matches the request to resource* Swagger2ApiListingResource*
with
JPU> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*
JPU> process(…)* method.

JPU> è       Here it seems to go wrong. It generates a SwaggerContextService
JPU> having basePath=/op/services/resources/,swaggerConfig=null,
JPU> usePathBasedConfig=null and then calls
JPU> SwaggerContextService.getSwagger()

JPU> which returns the Swagger definition for interface KmopApiServer?
JPU> It looks like it caches generated swagger definitions based on a
JPU> configIdKey with prefix ’swagger.config.id.xxx’. This key is the
JPU> same for all 3 interfaces as usePathBasedConfig=null

JPU> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is
JPU> derived from the ServletConfig parameter
JPU> ‘swagger.use.path.based.config’.* So should this be set on the
JPU> declaration of the CXFServlet** in web.xml?*

JPU> è       Actually the SwaggerConfig, the JaxrsScanner and the generated
Swagger
JPU> are cached using keys like
JPU> ‘swagger.config.id.[default|baseUriPath]’, ‘
JPU> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’ is
only done when usePathBasedconfig=true.

JPU> è       If I patch this to true then configIdKey=’
JPU> swagger.config.id./op/services/resources/’ and no swagger entry is
JPU> cached for this key so it will generate a new one. Again by
JPU> patching
JPU> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=true

JPU> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”

JPU> è       Again Scanners are cached and if usePathBasedConfig=null it
will use
JPU> the one cached under  ‘swagger.scanner.id.default’ and this again
JPU> returns the swagger definition for the KmopApiService interface.

JPU> è       So patching usePathBasedConfig=true will return a new one
JPU> (DefaultJaxrsScanner). The classes to scan for in this new scanner
JPU> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘
JPU> which is correct. It will generate a new (but empty) Swagger object.

JPU> è       Next Swagger2ApiListingResource will call the
JPU> customizer.customize(s), which still isn’t putting anything new in
JPU> the Swagger object. Should it or should the next step do this?

JPU> è       Next BaseApiListingResource#getListing(…) is called which on
its
JPU> turn calls getListingYamlResponse(..)

JPU> è       The final result is a swagger.yaml document with following
content:

JPU>    swagger: "2.0"

JPU>       info:

JPU>         license:

JPU>           name: "Apache 2.0 License"

JPU>           url: http://www.apache.org/licenses/LICENSE-2.0.html

JPU>       basePath: "/op/services/resources"

JPU>        So basically an empty swagger file.

JPU> d)      The usePathBasedConfig is derived from the ServletConfig
parameter ‘
JPU> swagger.use.path.based.config’. Without this parameter set to true
JPU> there will be only one Swaggerconfig, JaxrsScanner and Swagger
JPU> object.* So should this be set on the declaration of the
JPU> CXFServlet** in web.xml?*

JPU> The majority in this processing happens in the library
JPU> swagger-jaxrs-v1.6.10 which is included as a dependency on
cxf-rt-rs-service-description-swagger.
JPU> Even if I patch usePathBasedConfig=true about everywhere where I
JPU> met this it still doesn’t generate a correct swagger.yaml. Am I
JPU> still missing some configuration parameter?

JPU> Any suggestions on how to resolve this would be welcome.

JPU> Regards,

JPU> J.P. Urkens











JPU> <<...>> <<...>>

JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: maandag 8 mei 2023 23:15
JPU> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev
JPU> List <
dev@cxf.apache.org>>
JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

JPU> Indeed the way you would like to do that is somewhat tricky.

>> So I tried to keep the @Path declaration on the interface classes but
JPU> changed them to @Path(“”). That does seems to work except the
JPU> swagger stuff no longer correctly works.

JPU> This is one of the possible options but OpenAPI/Swagger gets
JPU> confused for a
JPU> reason: the path is now implicit (not in the spec).

JPU> So how about this option:

JPU>  - use only one JAX-RS server (address "/")

JPU>  - host both resources but use @Path("accounts") and
JPU> @Path("resources") on them respectively



JPU> I see that for @Path("accounts") you need to apply the
JPU> "kmopApiAuthorizationFilter", that could be done using
JPU> DynamicFeature [1], [2]. If this is not the option and you would
JPU> prefer to use 2 separate JAX-RS servers, you may need to provide
JPU> your own instance of Swagger2Customizer [3], [4] which allows to
JPU> transform the OpenAPI/Swagger on the fly. Please let me know if that
would it work for you, thank you.

JPU> [1]
JPU> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/DynamicF
JPU> eature.html

JPU> [2]
JPU> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born-
JPU> equal.html

JPU> [3]
JPU> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger/
JPU> Swagger2Customizer.html

JPU> [4] https://cxf.apache.org/docs/swagger2feature.html (has
JPU> customizer
JPU> property)



JPU> Best Regards,

JPU>     Andriy Redko

>> Hi Andriy,

>> I am again getting into trouble with server endpoint declarations.
>> Now
JPU> because I am adding additional JAX-RS endpoints.

>> The issue is with:

>> 1.      The 'address' attribute on the <jaxrs:server> declaration in
JPU> combination with

>> 2.      The 'url-pattern' for the CXFServlet declaration in the web.xml
JPU> in combination with

>> 3.      The @Path declaration in the interface class in combination with

>> 4.      The @Path declaration on the interface method in combination with

>> So what I had is that my web application deployed under baseUlr 'op'
>> had
JPU> one JAXRS server endpoint with declarations like:

>> 1.      <jaxrs:server id="restServer"
JPU> basePackages="be.dvtm.aeo.op.sodexo" address="/">

>> 2.      <url-pattern>/services/*</url-pattern>

>> 3.      @Path("accounts") on the public interface class

>> 4.      @Path("/{authorisationId}/customerFund") on the customerFund
JPU> interface method

>> A valid API call would thus be e.g.:

>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/cust
>> o

>> merFund

>> And this works correctly.

>> We're now introducing additional JAX-RS service endpoints and now I
>> am
JPU> running into problems. This second endpoint was declared with:

>> 1.      <jaxrs:server id="resourceServer"
JPU> basePackages="be.dvtm.aeo.op.resources" address="/">

>> 2.      <url-pattern>/services/*</url-pattern>

>> 3.      @Path("resources") on the public interface class

>> 4.      @Path("/NACE") on the NACE interface method

>> So here a valid API call woud be:
JPU> https://<hostname>:<port>/op/services/resources/NACE.

>> The problem is that I can not declare two <jaxrs:server> entries with
>> the
JPU> same ‘address’ as it throws the exception:

>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:
JPU> There is an endpoint already running on /.

>>  So I tried changing the addresses to:

>> ·       address=”accounts” for the restServer

>> ·       address=”resources” for the resourceServer

>> But to keep the API-call URLs the same I removed the @Path
>> declaration on
JPU> the interface classes. By doing so the <jaxrs:server> bean
JPU> declarations no longer loads successfully.

>> So I tried to keep the @Path declaration on the interface classes but
JPU> changed them to @Path(“”). That does seems to work except the
JPU> swagger stuff no longer correctly works.

>> So what is the decent way to setup multiple JAX-RS server endpoints
>> where
JPU> each server has its own configuration regarding supported features:

>> ·       own validation

>> ·       own object and exception mappings

>> ·       own swagger file generation

>> ·       own logging (in separate file if possible)

>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in
>> cooperation
JPU> with swager-ui v4.5.0.

>> Below the declarations of my endpoints <<...>> Thanks for any advice.

>> Regards,

>> J.P. Urkens

>> -----Original Message-----

>> From: Andriy Redko <dr...@gmail.com>

>> Sent: zaterdag 18 juni 2022 1:12

>> To: Jean Pierre URKENS <je...@devoteam.com>;

>> issues@cxf.apache.org; dev@cxf.apache.org

>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,

>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'

>> Correct, so in the relative form like address="/<something>", the
>> JAX-RS
JPU> endpoint path would be:

>>     <baseUrl>/<servlet path

>> mapping>/<address>/[@ApplicationPath]/[@Path]

>> The @ApplicationPath is optional in this case.

>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'

>> The JAX-WS is very different from JAX-RS, essentially the action
>> comes
JPU> inside the SOAP message behind <baseUrl>/<servlet path mapping>/
JPU> (@Path / @ApplicationPath are not relevant there).

>>> Question: Because now address="/" is set for the jaxrs:server will
>>> it

>>> also inspect requests targeted for the jaxws service as those

>>> requests have start with the same path '/<basePath>/services/...

>> This is a good question, I have not done it myself but I think it
>> should
JPU> work:

>> the servlet dispatches according to registered services, in this
>> regard
JPU> JAX-RS and JAX-WS should not conflict. Does it work in your case? Thank
you.

>> Best Regards,

>>     Andriy Redko

>>> Hi Andriy,

>>> Using address="/" seems to work but still I don't understand how the

>>> following work together:

>>>  - path specification in servlet mapping for the CXF servlet

>>> (org.apache.cxf.transport.servlet.CXFServlet)

>>>  - the 'address' attribute on the jaxrs:server bean declaration

>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the

>>> service API description Say I've two services with (relateive to the

>>> host) url's:

>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'

>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'

>>> How do I configure above 3 aspects? Currently I have (working):

>>> 1.for the jaxrs:server endpoint:

>>>         - servlet path mapping: '/services/*'

>>>                - jaxrs-server address attribute: address="/"

>>>                - @Path annotation: @Path("service1") 2.For the jaxws

>>> service endpoint:

>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS

>>> requests are handleb by the same CXF servle)

>>>                - jaxws:endpoint server address attribute:

>>> address="/service2"

>>>                - @WebService(name="service2") A correct request for

>>> '1' would be '/basePath>/services/service1/<ID>'.

>>> A correct request for '2' would be '/basePath>/services/service2'.

>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:

>>>         - the server address attribute

>>>         - The API annotation (@Path or @Webservice) The JAXWS server

>>> address attribute doesn't seem to interfere with the @Webservice

>>> annotation. While the jaxrs server address attribute does seem to

>>> interfere with the @Path annotation. I would have expected the jaxrs

>>> server aspects to be configured as:

>>>         - servlet path mapping: '/services/*'

>>>                - jaxrs-server address attribute: address="/service1"

>>>                - @Path annotation: @Path("service1") but then a
>>> valid

>>> request would be

>>>> /services/service1/service1/<ID>'.

>>> For both the 'address' attribute is relative to the servlet path.

>>> The @Path Javadoc mentions that this path is relative to the

>>> ApplicationPath which thus seems to be relative to the jaxrs-server

>>> address attribute. As for @Webservice it doesnn't seem to be
>>> url-path
JPU> related.

>>> Question: Because now address="/" is set for the jaxrs:server will
>>> it

>>> also inspect requests targeted for the jaxws service as those

>>> requests have start with the same path '/<basePath>/services/...'.

>>> Albeit somewhat confusing.

>>> J.P.

>>> -----Original Message-----

>>> From: Andriy Redko <dr...@gmail.com>

>>> Sent: dinsdag 14 juni 2022 1:08

>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>> issues@cxf.apache.org; dev@cxf.apache.org

>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,

>>> Indeed, the jaxrs:server does not expect address to be omitted, you

>>> could use the "/" (and I believe an empty string would also make it):

>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...

>>> </jaxrs:server>

>>> Thank you.

>>> Hope it helps.

>>> Best Regards,

>>>     Andriy Redko

>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean

>>>> declarations

>>>> like:

>>>>      <jaxrs:server id="restServer" basePackages="xxx">

>>>>            <jaxrs:serviceBeans>

>>>>                 <ref bean="TestApi" />

>>>>            </jaxrs:serviceBeans>

>>>>            <jaxrs:providers>

>>>>                 <…/>

>>>>            </jaxrs:providers>

>>>>            <jaxrs:features>

>>>>                 <… />

>>>>            </jaxrs:features>

>>>>            <jaxrs:inInterceptors>

>>>>                 <… />

>>>>            </jaxrs:inInterceptors>

>>>>            <jaxrs:outInterceptors>*

>>>>                 <**…**/>*

>>>>            </jaxrs:outInterceptors>*

>>>>      </jaxrs:server>



>>>> Here my “TestApi” bean interface is declared like:

>>>>       @Path("accounts")

>>>>        @Consumes(MediaType.*APPLICATION_JSON*)

>>>>        @Produces(MediaType.*APPLICATION_JSON*)

>>>>        public interface TestApi {

>>>>          …

>>>>        }

>>>> And CXF is triggered via a servlet configuration like:

>>>>      <servlet>

>>>>              <display-name>CXF Servlet</display-name>

>>>>              <servlet-name>CXFServlet</servlet-name>

>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servle

>>>> t

-class>>>>>

>>>>        </servlet>

>>>>        <servlet-mapping>

>>>>              <servlet-name>CXFServlet</servlet-name>

>>>>              <url-pattern>/services/*</url-pattern>

>>>>        </servlet-mapping>



>>>> Because I’ve got the @Path declaration on the interface type I’ve

>>>> omitted

>>>> the address=”accounts” attribute on the jaxrs:server declaration

>>>> since otherwise

>>>> I noticed that the server would be listening to

>>>> /basepath/services/ accounts/accounts/…).

>>>> Now this configuration works perfectly, only when shutting down

>>>> the application server cxf calls

>>>>         ServerImpl#destroy()

>>>> which delegates (via Obeservable) to

>>>> AbstractHTTPDestination#deactivate()

>>>> which calls

>>>> registry.removeDestination(path).

>>>> This path is null (no ‘address’ specified on jaxrs:server

>>>> declaration) and results in a NPE on the registry Map.

>>>> This causes an unclean shutdown of my server.

>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?

>>>> How does the ‘address’ attribute on the jaxrs:server declaration

>>>> correctly interact with the @Path parameter on the API interface?

JPU> <<...>>

Re: How to setup multiple JAXRS server endpoints

Posted by Andriy Redko <dr...@gmail.com>.
Hi Jean,

The main problem to configure Swagger property in your particular case is that
the server address is not "known" or "introspectable" for Swagger. Intuitively, 
it has to be set manually using basePath to the, essentially, the server address 
part:

 - /op/services/accounts
 - /op/services/resources
 - /op/services/dienstverlener

You could read more about other Swagger properties you have asked here: https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties

You definitely need to set usePathBasedConfig to "true" otherwise you will see
the same Swagger specs for all servers. We have a sample here which uses 2 jaxrs:server
instances: https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/main/release/samples/jax_rs/description_swagger2_web

Regarding SwaggerUI, I think the value for each of those should be set to, respectively: 

 - /op/services/accounts/swagger.yaml
 - /op/services/resources/swagger.yaml
 - /op/services/dienstverlener/swagger.yaml

I believe this is matching your settings already, except the usePathBasedConfig part. The example referred
above could be helpful, my apologies if I missed something, there are quite a lot of questions :-) The fact that
the generated Swagger specification is empty is unexpected - it should not happen when JAX-RS resources are 
properly configured.

Thank you.

Best Regards,
    Andriy Redko

JPU>  RE: How to setup multiple JAXRS server endpoints

JPU> Hi Andriy,

JPU> I am not quite understanding how to correctly configure the Swagger2Feature.

JPU> Referring to the attached cxf-endpoints configuration I (as a test) created
JPU> 3 JAXRS server instances:

JPU> 1.      A* KmopApiServer* server for the*
JPU> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving requests for
JPU> URI path:
JPU>        * <protocol>**//<host:<port>/op/services/accounts*

JPU>    ‘op’  = root path of the web application

JPU>             ‘services’ = servlet path of the CXF-servlet

JPU>       The address of the server is set to ‘/accounts’ and the @Path(…)
JPU>       annotation on the interface class was cleared.

JPU> 2.      A* Kmop**Resources**ApiServer* server for the* be.dvtm.aeo.op.*
JPU> *openapi.**api.Kmop**Recources**ApiService* interface, serving requests for
JPU> URI path:
JPU>        * <protocol>**//<host:<port>/op/services/**resources*
JPU> The address of the server is set to ‘/resources’ and the @Path(…)
JPU> annotation on the interface class was cleared.

JPU> 3.      A* Kmop**Dienstverlener**Server* server for the* be.dvtm.aeo.op.*
JPU> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving requests
JPU> for URI path:
JPU>        * <protocol>**//<host:<port>/op/services/**dienstverlener*
JPU> The address of the server is set to ‘/dienstverlener’ and the @Path(…)
JPU> annotation on the interface class was cleared.

JPU> For each of these server instances I’ve set the Swagger2Feature with
JPU> configuration as indicated in the attached cxf-endpoints.xml.

JPU> With regard to the configurations for the Swagger2Feature I’ve the
JPU> following questions:

JPU> a)      Referring to *https://cxf.apache.org/docs/swagger2feature.html*
JPU> <https://cxf.apache.org/docs/swagger2feature.html>  could you clarify on
JPU> the following configuration parameters:

JPU> *i.     ** basePath* – Is this the path to the CXFServlet context (‘
JPU> /op/services’) or to the JAX-RS server instance (e.g.
JPU> ‘/op/services/accounts’) or still something else? Is it used to resolve
JPU> service classes or is it just for documentation in the swagger file?

JPU> *ii.    ** resourcePackage* – the description mentions ‘package names’
JPU> while the default mentions ‘service classes’? Service 2 and 3 above are
JPU> within the same package (generated from the same yaml specification that
JPU> included both interfaces).

JPU> *iii.   ** ig**noreRoutes* – is this taken into account when
JPU> scanAllResources=false?

JPU> *iv.    ** swaggerUiConfig* – What is the correct ‘url’ parameter value
JPU> (cf. question ‘a’)?

JPU> b)      What would be the correct URL to generate a swagger.yaml file for
JPU> each of the above interfaces? Initially I called:

JPU> *i.     ** <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*

JPU> *ii.    ** <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*

JPU> *iii.   ** <protocol>**//<host:<port>/op/services/**dienstver*
JPU> *lener/swagger.yaml*

JPU>    All three requests delivered the same yaml specification, namely the one
JPU>       for interface* KmopApiServer*?

JPU> c)      I tried to debug the processing of the requests under ‘b)’ and this
JPU> is done by the class JAXRSInterceptor#processRequest where the MessageImpl
JPU> object for request “ii.” looks like the one attached. It finds 3 resource
JPU> classes:

JPU>    be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl

JPU>       org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource

JPU>       org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService

JPU> è       It matches the request to resource* Swagger2ApiListingResource* with
JPU> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its* process(…)*
JPU> method.

JPU> è       Here it seems to go wrong. It generates a SwaggerContextService
JPU> having basePath=/op/services/resources/,swaggerConfig=null,
JPU> usePathBasedConfig=null and then calls SwaggerContextService.getSwagger()

JPU> which returns the Swagger definition for interface KmopApiServer? It looks
JPU> like it caches generated swagger definitions based on a configIdKey with
JPU> prefix ’swagger.config.id.xxx’. This key is the same for all 3 interfaces
JPU> as usePathBasedConfig=null

JPU> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is derived
JPU> from the ServletConfig parameter ‘swagger.use.path.based.config’.* So
JPU> should this be set on the declaration of the CXFServlet** in web.xml?*

JPU> è       Actually the SwaggerConfig, the JaxrsScanner and the generated Swagger
JPU> are cached using keys like ‘swagger.config.id.[default|baseUriPath]’, ‘
JPU> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’ is
JPU> only done when usePathBasedconfig=true.

JPU> è       If I patch this to true then configIdKey=’
JPU> swagger.config.id./op/services/resources/’ and no swagger entry is cached
JPU> for this key so it will generate a new one. Again by patching
JPU> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=true

JPU> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”

JPU> è       Again Scanners are cached and if usePathBasedConfig=null it will use
JPU> the one cached under  ‘swagger.scanner.id.default’ and this again returns
JPU> the swagger definition for the KmopApiService interface.

JPU> è       So patching usePathBasedConfig=true will return a new one
JPU> (DefaultJaxrsScanner). The classes to scan for in this new scanner are ‘
JPU> be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘ which is
JPU> correct. It will generate a new (but empty) Swagger object.

JPU> è       Next Swagger2ApiListingResource will call the
JPU> customizer.customize(s), which still isn’t putting anything new in the
JPU> Swagger object. Should it or should the next step do this?

JPU> è       Next BaseApiListingResource#getListing(…) is called which on its
JPU> turn calls getListingYamlResponse(..)

JPU> è       The final result is a swagger.yaml document with following content:

JPU>    swagger: "2.0"

JPU>       info:

JPU>         license:

JPU>           name: "Apache 2.0 License"

JPU>           url: http://www.apache.org/licenses/LICENSE-2.0.html

JPU>       basePath: "/op/services/resources"

JPU>        So basically an empty swagger file.

JPU> d)      The usePathBasedConfig is derived from the ServletConfig parameter ‘
JPU> swagger.use.path.based.config’. Without this parameter set to true there
JPU> will be only one Swaggerconfig, JaxrsScanner and Swagger object.* So should
JPU> this be set on the declaration of the CXFServlet** in web.xml?*

JPU> The majority in this processing happens in the library swagger-jaxrs-v1.6.10
JPU> which is included as a dependency on cxf-rt-rs-service-description-swagger.
JPU> Even if I patch usePathBasedConfig=true about everywhere where I met this
JPU> it still doesn’t generate a correct swagger.yaml. Am I still missing some
JPU> configuration parameter?

JPU> Any suggestions on how to resolve this would be welcome.

JPU> Regards,

JPU> J.P. Urkens











JPU> <<...>> <<...>>

JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: maandag 8 mei 2023 23:15
JPU> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev List <
dev@cxf.apache.org>>
JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

JPU> Indeed the way you would like to do that is somewhat tricky.

>> So I tried to keep the @Path declaration on the interface classes but
JPU> changed them to @Path(“”). That does seems to work except the swagger stuff
JPU> no longer correctly works.

JPU> This is one of the possible options but OpenAPI/Swagger gets confused for a
JPU> reason: the path is now implicit (not in the spec).

JPU> So how about this option:

JPU>  - use only one JAX-RS server (address "/")

JPU>  - host both resources but use @Path("accounts") and @Path("resources") on
JPU> them respectively



JPU> I see that for @Path("accounts") you need to apply the
JPU> "kmopApiAuthorizationFilter", that could be done using DynamicFeature [1],
JPU> [2]. If this is not the option and you would prefer to use 2 separate
JPU> JAX-RS servers, you may need to provide your own instance of
JPU> Swagger2Customizer [3], [4] which allows to transform the OpenAPI/Swagger
JPU> on the fly. Please let me know if that would it work for you, thank you.

JPU> [1]
JPU> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/DynamicFeature.html

JPU> [2]
JPU> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born-equal.html

JPU> [3]
JPU> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger/Swagger2Customizer.html

JPU> [4] https://cxf.apache.org/docs/swagger2feature.html (has customizer
JPU> property)



JPU> Best Regards,

JPU>     Andriy Redko

>> Hi Andriy,

>> I am again getting into trouble with server endpoint declarations. Now
JPU> because I am adding additional JAX-RS endpoints.

>> The issue is with:

>> 1.      The 'address' attribute on the <jaxrs:server> declaration in
JPU> combination with

>> 2.      The 'url-pattern' for the CXFServlet declaration in the web.xml
JPU> in combination with

>> 3.      The @Path declaration in the interface class in combination with

>> 4.      The @Path declaration on the interface method in combination with

>> So what I had is that my web application deployed under baseUlr 'op' had
JPU> one JAXRS server endpoint with declarations like:

>> 1.      <jaxrs:server id="restServer"
JPU> basePackages="be.dvtm.aeo.op.sodexo" address="/">

>> 2.      <url-pattern>/services/*</url-pattern>

>> 3.      @Path("accounts") on the public interface class

>> 4.      @Path("/{authorisationId}/customerFund") on the customerFund
JPU> interface method

>> A valid API call would thus be e.g.:

>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/custo

>> merFund

>> And this works correctly.

>> We're now introducing additional JAX-RS service endpoints and now I am
JPU> running into problems. This second endpoint was declared with:

>> 1.      <jaxrs:server id="resourceServer"
JPU> basePackages="be.dvtm.aeo.op.resources" address="/">

>> 2.      <url-pattern>/services/*</url-pattern>

>> 3.      @Path("resources") on the public interface class

>> 4.      @Path("/NACE") on the NACE interface method

>> So here a valid API call woud be:
JPU> https://<hostname>:<port>/op/services/resources/NACE.

>> The problem is that I can not declare two <jaxrs:server> entries with the
JPU> same ‘address’ as it throws the exception:

>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:
JPU> There is an endpoint already running on /.

>>  So I tried changing the addresses to:

>> ·       address=”accounts” for the restServer

>> ·       address=”resources” for the resourceServer

>> But to keep the API-call URLs the same I removed the @Path declaration on
JPU> the interface classes. By doing so the <jaxrs:server> bean declarations no
JPU> longer loads successfully.

>> So I tried to keep the @Path declaration on the interface classes but
JPU> changed them to @Path(“”). That does seems to work except the swagger stuff
JPU> no longer correctly works.

>> So what is the decent way to setup multiple JAX-RS server endpoints where
JPU> each server has its own configuration regarding supported features:

>> ·       own validation

>> ·       own object and exception mappings

>> ·       own swagger file generation

>> ·       own logging (in separate file if possible)

>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in cooperation
JPU> with swager-ui v4.5.0.

>> Below the declarations of my endpoints <<...>> Thanks for any advice.

>> Regards,

>> J.P. Urkens

>> -----Original Message-----

>> From: Andriy Redko <dr...@gmail.com>

>> Sent: zaterdag 18 juni 2022 1:12

>> To: Jean Pierre URKENS <je...@devoteam.com>;

>> issues@cxf.apache.org; dev@cxf.apache.org

>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,

>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'

>> Correct, so in the relative form like address="/<something>", the JAX-RS
JPU> endpoint path would be:

>>     <baseUrl>/<servlet path

>> mapping>/<address>/[@ApplicationPath]/[@Path]

>> The @ApplicationPath is optional in this case.

>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'

>> The JAX-WS is very different from JAX-RS, essentially the action comes
JPU> inside the SOAP message behind <baseUrl>/<servlet path mapping>/ (@Path /
JPU> @ApplicationPath are not relevant there).

>>> Question: Because now address="/" is set for the jaxrs:server will it

>>> also inspect requests targeted for the jaxws service as those

>>> requests have start with the same path '/<basePath>/services/...

>> This is a good question, I have not done it myself but I think it should
JPU> work:

>> the servlet dispatches according to registered services, in this regard
JPU> JAX-RS and JAX-WS should not conflict. Does it work in your case? Thank you.

>> Best Regards,

>>     Andriy Redko

>>> Hi Andriy,

>>> Using address="/" seems to work but still I don't understand how the

>>> following work together:

>>>  - path specification in servlet mapping for the CXF servlet

>>> (org.apache.cxf.transport.servlet.CXFServlet)

>>>  - the 'address' attribute on the jaxrs:server bean declaration

>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the

>>> service API description Say I've two services with (relateive to the

>>> host) url's:

>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'

>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'

>>> How do I configure above 3 aspects? Currently I have (working):

>>> 1.for the jaxrs:server endpoint:

>>>         - servlet path mapping: '/services/*'

>>>                - jaxrs-server address attribute: address="/"

>>>                - @Path annotation: @Path("service1") 2.For the jaxws

>>> service endpoint:

>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS

>>> requests are handleb by the same CXF servle)

>>>                - jaxws:endpoint server address attribute:

>>> address="/service2"

>>>                - @WebService(name="service2") A correct request for

>>> '1' would be '/basePath>/services/service1/<ID>'.

>>> A correct request for '2' would be '/basePath>/services/service2'.

>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:

>>>         - the server address attribute

>>>         - The API annotation (@Path or @Webservice) The JAXWS server

>>> address attribute doesn't seem to interfere with the @Webservice

>>> annotation. While the jaxrs server address attribute does seem to

>>> interfere with the @Path annotation. I would have expected the jaxrs

>>> server aspects to be configured as:

>>>         - servlet path mapping: '/services/*'

>>>                - jaxrs-server address attribute: address="/service1"

>>>                - @Path annotation: @Path("service1") but then a valid

>>> request would be

>>>> /services/service1/service1/<ID>'.

>>> For both the 'address' attribute is relative to the servlet path.

>>> The @Path Javadoc mentions that this path is relative to the

>>> ApplicationPath which thus seems to be relative to the jaxrs-server

>>> address attribute. As for @Webservice it doesnn't seem to be url-path
JPU> related.

>>> Question: Because now address="/" is set for the jaxrs:server will it

>>> also inspect requests targeted for the jaxws service as those

>>> requests have start with the same path '/<basePath>/services/...'.

>>> Albeit somewhat confusing.

>>> J.P.

>>> -----Original Message-----

>>> From: Andriy Redko <dr...@gmail.com>

>>> Sent: dinsdag 14 juni 2022 1:08

>>> To: Jean Pierre URKENS <je...@devoteam.com>;

>>> issues@cxf.apache.org; dev@cxf.apache.org

>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,

>>> Indeed, the jaxrs:server does not expect address to be omitted, you

>>> could use the "/" (and I believe an empty string would also make it):

>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...

>>> </jaxrs:server>

>>> Thank you.

>>> Hope it helps.

>>> Best Regards,

>>>     Andriy Redko

>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean

>>>> declarations

>>>> like:

>>>>      <jaxrs:server id="restServer" basePackages="xxx">

>>>>            <jaxrs:serviceBeans>

>>>>                 <ref bean="TestApi" />

>>>>            </jaxrs:serviceBeans>

>>>>            <jaxrs:providers>

>>>>                 <…/>

>>>>            </jaxrs:providers>

>>>>            <jaxrs:features>

>>>>                 <… />

>>>>            </jaxrs:features>

>>>>            <jaxrs:inInterceptors>

>>>>                 <… />

>>>>            </jaxrs:inInterceptors>

>>>>            <jaxrs:outInterceptors>*

>>>>                 <**…**/>*

>>>>            </jaxrs:outInterceptors>*

>>>>      </jaxrs:server>



>>>> Here my “TestApi” bean interface is declared like:

>>>>       @Path("accounts")

>>>>        @Consumes(MediaType.*APPLICATION_JSON*)

>>>>        @Produces(MediaType.*APPLICATION_JSON*)

>>>>        public interface TestApi {

>>>>          …

>>>>        }

>>>> And CXF is triggered via a servlet configuration like:

>>>>      <servlet>

>>>>              <display-name>CXF Servlet</display-name>

>>>>              <servlet-name>CXFServlet</servlet-name>

>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servle

>>>> t

-class>>>>>

>>>>        </servlet>

>>>>        <servlet-mapping>

>>>>              <servlet-name>CXFServlet</servlet-name>

>>>>              <url-pattern>/services/*</url-pattern>

>>>>        </servlet-mapping>



>>>> Because I’ve got the @Path declaration on the interface type I’ve

>>>> omitted

>>>> the address=”accounts” attribute on the jaxrs:server declaration

>>>> since otherwise

>>>> I noticed that the server would be listening to

>>>> /basepath/services/ accounts/accounts/…).

>>>> Now this configuration works perfectly, only when shutting down

>>>> the application server cxf calls

>>>>         ServerImpl#destroy()

>>>> which delegates (via Obeservable) to

>>>> AbstractHTTPDestination#deactivate()

>>>> which calls

>>>> registry.removeDestination(path).

>>>> This path is null (no ‘address’ specified on jaxrs:server

>>>> declaration) and results in a NPE on the registry Map.

>>>> This causes an unclean shutdown of my server.

>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?

>>>> How does the ‘address’ attribute on the jaxrs:server declaration

>>>> correctly interact with the @Path parameter on the API interface?

JPU> <<...>>


Re: How to setup multiple JAXRS server endpoints

Posted by Andriy Redko <dr...@gmail.com>.
Thank you for invaluable feedback, the documentation has been updated to 
have better explanation [1], [2].

[1] https://cwiki.apache.org/confluence/display/CXF20DOC/Swagger2Feature
[2] https://cwiki.apache.org/confluence/display/CXF20DOC/OpenApiFeature

Best Regards,
    Andriy Redko

Friday, May 19, 2023, 4:28:05 AM, you wrote:

JPU> This explanation makes sense but that wasn't clear from the WIKI page.

JPU> Regards,

JPU> J.P.

JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: vrijdag 19 mei 2023 3:04
JPU> To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

>> Am I misinterpreting this statement? It sounds to me that it should
>> work with 'queryConfigEnabled=true' instead of 'queryConfigEnabled=false'?

JPU> It could be a bit confusing but I will try to explain (please let me know if
JPU> it makes sense to you):

JPU>  - when 'queryConfigEnabled=false', CXF will dynamically replace the URL in
JPU> SwaggerUI,
JPU>    in this respect the value won't be taken from the query string but from
JPU> `url` property
JPU>    of the SwaggerUI configuration

JPU>  - when 'queryConfigEnabled=true', CXF will do nothing and just forward
JPU> query parameters to
JPU>    SwaggerUI, hoping it will somehow take care of it (basically turns off
JPU> the URL replacement),
JPU>    that needs custom SwaggerUI distribution

JPU> I hope it explains the behavior, please let me know if it is still
JPU> misleading (so we could improve the documentation). Thank you.

JPU> Best Regards,
JPU>     Andriy Redko

JPU>> Hi andriy,

JPU>> I started off with looking at this swagger but prior to that I
JPU>> updated framework versions. I am now on:
JPU>>          - CXF v3.5.6
JPU>>          - Swagger-UI v4.14.0

JPU>> I noticed things changed with respect to the Swagger2Feature and
JPU>> SwaggerUiConfig due to https://issues.apache.org/jira/browse/CXF-8636.

JPU>> When reading
JPU>> https://cwiki.apache.org/confluence/display/CXF20DOC/Swagger2Featur
JPU>> e#Swagger2Feature-ConfiguringSwaggerUI(3.2.7+)
JPU>> I
JPU>> reconfigured the usage of the swagger features as:

JPU>>         <!-- CXF Swagger2Feature -->
JPU>>         <bean id="SwaggerUiConfig"
JPU>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">
JPU>>                 <property name="queryConfigEnabled" value="true"/>
JPU>>                 <property name="url" value="swagger.yaml"/>
JPU>>         </bean>
JPU>>         <bean id="swagger2Feature"
JPU>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">
JPU>>                 <property name="supportSwaggerUi" value="true" />
JPU>>                 <property name="swaggerUiConfig"
JPU> ref="SwaggerUiConfig"/>
JPU>>         </bean>

JPU>> With this configuration:
JPU>> * Retrieving the swagger.yaml specification works with the url:
JPU>> http://l-p53-008:8082/idp/rest-services/swagger.yaml ('idp' is the
JPU>> war rootpath and 'rest-services' is the CXF-servlet path)
JPU>> * Loading the Swagger UI with the url:
JPU>> http://l-p53-008:8082/idp/rest-services/api-docs?url=swagger.yaml
JPU>> FAILS ? It loads the petshop store yaml specification.

JPU>> When I change above configuration to:

JPU>>         <!-- CXF Swagger2Feature -->
JPU>>         <bean id="SwaggerUiConfig"
JPU>> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">
JPU>>                 <property name="queryConfigEnabled" value="false"/>
JPU>>                 <property name="url" value="swagger.yaml"/>
JPU>>         </bean>
JPU>>         <bean id="swagger2Feature"
JPU>> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">
JPU>>                 <property name="supportSwaggerUi" value="true" />
JPU>>                 <property name="swaggerUiConfig"
JPU> ref="SwaggerUiConfig"/>
JPU>>         </bean>

JPU>> Then:
JPU>> * Retrieving the swagger.yaml specification works with the url:
JPU>> http://l-p53-008:8082/idp/rest-services/swagger.yaml ('idp' is the
JPU>> war rootpath and 'rest-services' is the CXF-servlet path)
JPU>> * Loading the Swagger UI with the url:
JPU>> http://l-p53-008:8082/idp/rest-services/api-docs?url=swagger.yaml
JPU> SUCCEEDS ?
JPU>> It loads the swagger.yaml specification.


JPU>> The confluence WIKI page above specifically mentions:
JPU>> "Apache CXF prior to 3.4.6 / 3.5.1 passed Swagger UI configuration
JPU>> (url,
JPU>> ...) as query parameters. Starting from Swagger UI 4.1.3, most of
JPU>> query parameters are not accepted anymore (due to security
JPU>> concerns), and Apache CXF employes different strategy and tries to
JPU>> replace the URL dynamically (inside HTML) when serving Swagger UI's
JPU>> front web page. This behaviour could be turned on by setting
JPU>> queryConfigEnabled  property of the SwaggerUiConfig to true (the
JPU> default value is false )."

JPU>> Am I misinterpreting this statement? It sounds to me that it should
JPU>> work with 'queryConfigEnabled=true' instead of
JPU> 'queryConfigEnabled=false'?



JPU>> -----Original Message-----
JPU>> From: Jean Pierre URKENS <je...@devoteam.com>
JPU>> Sent: dinsdag 9 mei 2023 9:25
JPU>> To: 'Andriy Redko' <dr...@gmail.com>
JPU>> Subject: RE: How to setup multiple JAXRS server endpoints

JPU>> Hi Andriy,

JPU>> Both servers have not only differences in 'authorization' but also
JPU>> in exception handling regarding mapping and validation errors
JPU>> that's why I can't use the same JAX-RS server bean for them. I'll
JPU>> have a look at customizing the swagger feature and will come back
JPU>> on it but for now getting the server up-and-running is more important.

JPU>> Regards,

JPU>> J.P. Urkens

JPU>> -----Original Message-----
JPU>> From: Andriy Redko <dr...@gmail.com>
JPU>> Sent: maandag 8 mei 2023 23:15
JPU>> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev
JPU>> List <de...@cxf.apache.org>
JPU>> Subject: Re: How to setup multiple JAXRS server endpoints

JPU>> Hi Jean,

JPU>> Indeed the way you would like to do that is somewhat tricky.

>>> So I tried to keep the @Path declaration on the interface classes but
>>> changed them to @Path(“”). That does seems to work except the swagger
>>> stuff no longer correctly works.

JPU>> This is one of the possible options but OpenAPI/Swagger gets
JPU>> confused for a
JPU>> reason: the path is now implicit (not in the spec).
JPU>> So how about this option:
JPU>>  - use only one JAX-RS server (address "/")
JPU>>  - host both resources but use @Path("accounts") and
JPU>> @Path("resources") on them respectively

JPU>> I see that for @Path("accounts") you need to apply the
JPU>> "kmopApiAuthorizationFilter", that could be done using
JPU>> DynamicFeature [1], [2]. If this is not the option and you would
JPU>> prefer to use 2 separate JAX-RS servers, you may need to provide
JPU>> your own instance of Swagger2Customizer [3], [4] which allows to
JPU>> transform the OpenAPI/Swagger on the fly. Please let me know if that
JPU> would it work for you, thank you.

JPU>> [1]
JPU>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/DynamicF
JPU>> eature.html
JPU>> [2]
JPU>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born-
JPU>> equal.html
JPU>> [3]
JPU>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger/
JPU>> Swagger2Customizer.html [4]
JPU>> https://cxf.apache.org/docs/swagger2feature.html (has customizer
JPU>> property)


JPU>> Best Regards,
JPU>>     Andriy Redko

>>> Hi Andriy,
>>> I am again getting into trouble with server endpoint declarations.
>>> Now because I am adding additional JAX-RS endpoints.
>>> The issue is with:
>>> 1.      The 'address' attribute on the <jaxrs:server> declaration in
>>> combination with
>>> 2.      The 'url-pattern' for the CXFServlet declaration in the web.xml
>>> in
>>> combination with
>>> 3.      The @Path declaration in the interface class in combination with
>>> 4.      The @Path declaration on the interface method in combination with
>>> So what I had is that my web application deployed under baseUlr 'op'
>>> had one JAXRS server endpoint with declarations like:
>>> 1.      <jaxrs:server id="restServer"
>>> basePackages="be.dvtm.aeo.op.sodexo"
>>> address="/">
>>> 2.      <url-pattern>/services/*</url-pattern>
>>> 3.      @Path("accounts") on the public interface class
>>> 4.      @Path("/{authorisationId}/customerFund") on the customerFund
>>> interface method
>>> A valid API call would thus be e.g.:
>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/cust
>>> o
>>> merFund
>>> And this works correctly.
>>> We're now introducing additional JAX-RS service endpoints and now I
>>> am running into problems. This second endpoint was declared with:
>>> 1.      <jaxrs:server id="resourceServer"
>>> basePackages="be.dvtm.aeo.op.resources" address="/">
>>> 2.      <url-pattern>/services/*</url-pattern>
>>> 3.      @Path("resources") on the public interface class
>>> 4.      @Path("/NACE") on the NACE interface method
>>> So here a valid API call woud be:
>>> https://<hostname>:<port>/op/services/resources/NACE.
>>> The problem is that I can not declare two <jaxrs:server> entries with
>>> the same ‘address’ as it throws the exception:
>>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:
>>> There is an endpoint already running on /.
>>>  So I tried changing the addresses to:
>>> ·       address=”accounts” for the restServer
>>> ·       address=”resources” for the resourceServer
>>> But to keep the API-call URLs the same I removed the @Path
>>> declaration on the interface classes. By doing so the <jaxrs:server>
>>> bean declarations no longer loads successfully.
>>> So I tried to keep the @Path declaration on the interface classes but
>>> changed them to @Path(“”). That does seems to work except the swagger
>>> stuff no longer correctly works.

>>> So what is the decent way to setup multiple JAX-RS server endpoints
>>> where each server has its own configuration regarding supported features:
>>> ·       own validation
>>> ·       own object and exception mappings
>>> ·       own swagger file generation
>>> ·       own logging (in separate file if possible)
>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in
>>> cooperation with swager-ui v4.5.0.
>>> Below the declarations of my endpoints <<...>> Thanks for any advice.
>>> Regards,
>>> J.P. Urkens

>>> -----Original Message-----
>>> From: Andriy Redko <dr...@gmail.com>
>>> Sent: zaterdag 18 juni 2022 1:12
>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>>> issues@cxf.apache.org; dev@cxf.apache.org
>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,
>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'
>>> Correct, so in the relative form like address="/<something>", the
>>> JAX-RS endpoint path would be:
>>>     <baseUrl>/<servlet path
>>> mapping>/<address>/[@ApplicationPath]/[@Path]
>>> The @ApplicationPath is optional in this case.
>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>>> The JAX-WS is very different from JAX-RS, essentially the action
>>> comes inside the SOAP message behind <baseUrl>/<servlet path
>>> mapping>/ (@Path / @ApplicationPath are not relevant there).

>>>> Question: Because now address="/" is set for the jaxrs:server will
>>>> it also inspect requests targeted for the jaxws service as those
>>>> requests have start with the same path '/<basePath>/services/...
>>> This is a good question, I have not done it myself but I think it
>>> should
>>> work:
>>> the servlet dispatches according to registered services, in this
>>> regard JAX-RS and JAX-WS should not conflict. Does it work in your
>>> case? Thank you.
>>> Best Regards,
>>>     Andriy Redko
>>>> Hi Andriy,
>>>> Using address="/" seems to work but still I don't understand how the
>>>> following work together:
>>>>  - path specification in servlet mapping for the CXF servlet
>>>> (org.apache.cxf.transport.servlet.CXFServlet)
>>>>  - the 'address' attribute on the jaxrs:server bean declaration
>>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the
>>>> service API description Say I've two services with (relateive to the
>>>> host) url's:
>>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'
>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>>>> How do I configure above 3 aspects? Currently I have (working):
>>>> 1.for the jaxrs:server endpoint:
>>>>         - servlet path mapping: '/services/*'
>>>>                - jaxrs-server address attribute: address="/"
>>>>                - @Path annotation: @Path("service1") 2.For the jaxws
>>>> service endpoint:
>>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS
>>>> requests are handleb by the same CXF servle)
>>>>                - jaxws:endpoint server address attribute:
>>>> address="/service2"
>>>>                - @WebService(name="service2") A correct request for
>>>> '1' would be '/basePath>/services/service1/<ID>'.
>>>> A correct request for '2' would be '/basePath>/services/service2'.
>>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:
>>>>         - the server address attribute
>>>>         - The API annotation (@Path or @Webservice) The JAXWS server
>>>> address attribute doesn't seem to interfere with the @Webservice
>>>> annotation. While the jaxrs server address attribute does seem to
>>>> interfere with the @Path annotation. I would have expected the jaxrs
>>>> server aspects to be configured as:
>>>>         - servlet path mapping: '/services/*'
>>>>                - jaxrs-server address attribute: address="/service1"
>>>>                - @Path annotation: @Path("service1") but then a
>>>> valid request would be
>>>>> /services/service1/service1/<ID>'.
>>>> For both the 'address' attribute is relative to the servlet path.
>>>> The @Path Javadoc mentions that this path is relative to the
>>>> ApplicationPath which thus seems to be relative to the jaxrs-server
>>>> address attribute. As for @Webservice it doesnn't seem to be
>>>> url-path related.
>>>> Question: Because now address="/" is set for the jaxrs:server will
>>>> it also inspect requests targeted for the jaxws service as those
>>>> requests have start with the same path '/<basePath>/services/...'.
>>>> Albeit somewhat confusing.
>>>> J.P.
>>>> -----Original Message-----
>>>> From: Andriy Redko <dr...@gmail.com>
>>>> Sent: dinsdag 14 juni 2022 1:08
>>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>>>> issues@cxf.apache.org; dev@cxf.apache.org
>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,
>>>> Indeed, the jaxrs:server does not expect address to be omitted, you
>>>> could use the "/" (and I believe an empty string would also make it):
>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...
>>>> </jaxrs:server>

>>>> Thank you.
>>>> Hope it helps.
>>>> Best Regards,
>>>>     Andriy Redko

>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean
>>>>> declarations
>>>>> like:
>>>>>      <jaxrs:server id="restServer" basePackages="xxx">
>>>>>            <jaxrs:serviceBeans>
>>>>>                 <ref bean="TestApi" />
>>>>>            </jaxrs:serviceBeans>
>>>>>            <jaxrs:providers>
>>>>>                 <…/>
>>>>>            </jaxrs:providers>
>>>>>            <jaxrs:features>
>>>>>                 <… />
>>>>>            </jaxrs:features>
>>>>>            <jaxrs:inInterceptors>
>>>>>                 <… />
>>>>>            </jaxrs:inInterceptors>
>>>>>            <jaxrs:outInterceptors>*
>>>>>                 <**…**/>*
>>>>>            </jaxrs:outInterceptors>*
>>>>>      </jaxrs:server>




>>>>> Here my “TestApi” bean interface is declared like:


>>>>>       @Path("accounts")
>>>>>        @Consumes(MediaType.*APPLICATION_JSON*)
>>>>>        @Produces(MediaType.*APPLICATION_JSON*)
>>>>>        public interface TestApi {
>>>>>          …
>>>>>        }


>>>>> And CXF is triggered via a servlet configuration like:
>>>>>      <servlet>
>>>>>              <display-name>CXF Servlet</display-name>
>>>>>              <servlet-name>CXFServlet</servlet-name>

>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servle
>>>>> t
-class>>>>>>
>>>>>        </servlet>
>>>>>        <servlet-mapping>
>>>>>              <servlet-name>CXFServlet</servlet-name>
>>>>>              <url-pattern>/services/*</url-pattern>
>>>>>        </servlet-mapping>




>>>>> Because I’ve got the @Path declaration on the interface type I’ve
>>>>> omitted the address=”accounts” attribute on the jaxrs:server
>>>>> declaration since otherwise I noticed that the server would be
>>>>> listening to /basepath/services/ accounts/accounts/…).


>>>>> Now this configuration works perfectly, only when shutting down the
>>>>> application server cxf calls
>>>>>         ServerImpl#destroy()


>>>>> which delegates (via Obeservable) to
>>>>> AbstractHTTPDestination#deactivate()
>>>>> which calls
>>>>> registry.removeDestination(path).
>>>>> This path is null (no ‘address’ specified on jaxrs:server
>>>>> declaration) and results in a NPE on the registry Map.
>>>>> This causes an unclean shutdown of my server.


>>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?
>>>>> How does the ‘address’ attribute on the jaxrs:server declaration
>>>>> correctly interact with the @Path parameter on the API interface?


RE: How to setup multiple JAXRS server endpoints

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
This explanation makes sense but that wasn't clear from the WIKI page.

Regards,

J.P.

-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: vrijdag 19 mei 2023 3:04
To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
Subject: Re: How to setup multiple JAXRS server endpoints

Hi Jean,

> Am I misinterpreting this statement? It sounds to me that it should
> work with 'queryConfigEnabled=true' instead of 'queryConfigEnabled=false'?

It could be a bit confusing but I will try to explain (please let me know if
it makes sense to you):

 - when 'queryConfigEnabled=false', CXF will dynamically replace the URL in
SwaggerUI,
   in this respect the value won't be taken from the query string but from
`url` property
   of the SwaggerUI configuration

 - when 'queryConfigEnabled=true', CXF will do nothing and just forward
query parameters to
   SwaggerUI, hoping it will somehow take care of it (basically turns off
the URL replacement),
   that needs custom SwaggerUI distribution

I hope it explains the behavior, please let me know if it is still
misleading (so we could improve the documentation). Thank you.

Best Regards,
    Andriy Redko

JPU> Hi andriy,

JPU> I started off with looking at this swagger but prior to that I
JPU> updated framework versions. I am now on:
JPU>          - CXF v3.5.6
JPU>          - Swagger-UI v4.14.0

JPU> I noticed things changed with respect to the Swagger2Feature and
JPU> SwaggerUiConfig due to https://issues.apache.org/jira/browse/CXF-8636.

JPU> When reading
JPU> https://cwiki.apache.org/confluence/display/CXF20DOC/Swagger2Featur
JPU> e#Swagger2Feature-ConfiguringSwaggerUI(3.2.7+)
JPU> I
JPU> reconfigured the usage of the swagger features as:

JPU>         <!-- CXF Swagger2Feature -->
JPU>         <bean id="SwaggerUiConfig"
JPU> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">
JPU>                 <property name="queryConfigEnabled" value="true"/>
JPU>                 <property name="url" value="swagger.yaml"/>
JPU>         </bean>
JPU>         <bean id="swagger2Feature"
JPU> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">
JPU>                 <property name="supportSwaggerUi" value="true" />
JPU>                 <property name="swaggerUiConfig"
ref="SwaggerUiConfig"/>
JPU>         </bean>

JPU> With this configuration:
JPU> * Retrieving the swagger.yaml specification works with the url:
JPU> http://l-p53-008:8082/idp/rest-services/swagger.yaml ('idp' is the
JPU> war rootpath and 'rest-services' is the CXF-servlet path)
JPU> * Loading the Swagger UI with the url:
JPU> http://l-p53-008:8082/idp/rest-services/api-docs?url=swagger.yaml
JPU> FAILS ? It loads the petshop store yaml specification.

JPU> When I change above configuration to:

JPU>         <!-- CXF Swagger2Feature -->
JPU>         <bean id="SwaggerUiConfig"
JPU> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">
JPU>                 <property name="queryConfigEnabled" value="false"/>
JPU>                 <property name="url" value="swagger.yaml"/>
JPU>         </bean>
JPU>         <bean id="swagger2Feature"
JPU> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">
JPU>                 <property name="supportSwaggerUi" value="true" />
JPU>                 <property name="swaggerUiConfig"
ref="SwaggerUiConfig"/>
JPU>         </bean>

JPU> Then:
JPU> * Retrieving the swagger.yaml specification works with the url:
JPU> http://l-p53-008:8082/idp/rest-services/swagger.yaml ('idp' is the
JPU> war rootpath and 'rest-services' is the CXF-servlet path)
JPU> * Loading the Swagger UI with the url:
JPU> http://l-p53-008:8082/idp/rest-services/api-docs?url=swagger.yaml
SUCCEEDS ?
JPU> It loads the swagger.yaml specification.


JPU> The confluence WIKI page above specifically mentions:
JPU> "Apache CXF prior to 3.4.6 / 3.5.1 passed Swagger UI configuration
JPU> (url,
JPU> ...) as query parameters. Starting from Swagger UI 4.1.3, most of
JPU> query parameters are not accepted anymore (due to security
JPU> concerns), and Apache CXF employes different strategy and tries to
JPU> replace the URL dynamically (inside HTML) when serving Swagger UI's
JPU> front web page. This behaviour could be turned on by setting
JPU> queryConfigEnabled  property of the SwaggerUiConfig to true (the
default value is false )."

JPU> Am I misinterpreting this statement? It sounds to me that it should
JPU> work with 'queryConfigEnabled=true' instead of
'queryConfigEnabled=false'?



JPU> -----Original Message-----
JPU> From: Jean Pierre URKENS <je...@devoteam.com>
JPU> Sent: dinsdag 9 mei 2023 9:25
JPU> To: 'Andriy Redko' <dr...@gmail.com>
JPU> Subject: RE: How to setup multiple JAXRS server endpoints

JPU> Hi Andriy,

JPU> Both servers have not only differences in 'authorization' but also
JPU> in exception handling regarding mapping and validation errors
JPU> that's why I can't use the same JAX-RS server bean for them. I'll
JPU> have a look at customizing the swagger feature and will come back
JPU> on it but for now getting the server up-and-running is more important.

JPU> Regards,

JPU> J.P. Urkens

JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: maandag 8 mei 2023 23:15
JPU> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev
JPU> List <de...@cxf.apache.org>
JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

JPU> Indeed the way you would like to do that is somewhat tricky.

>> So I tried to keep the @Path declaration on the interface classes but
>> changed them to @Path(“”). That does seems to work except the swagger
>> stuff no longer correctly works.

JPU> This is one of the possible options but OpenAPI/Swagger gets
JPU> confused for a
JPU> reason: the path is now implicit (not in the spec).
JPU> So how about this option:
JPU>  - use only one JAX-RS server (address "/")
JPU>  - host both resources but use @Path("accounts") and
JPU> @Path("resources") on them respectively

JPU> I see that for @Path("accounts") you need to apply the
JPU> "kmopApiAuthorizationFilter", that could be done using
JPU> DynamicFeature [1], [2]. If this is not the option and you would
JPU> prefer to use 2 separate JAX-RS servers, you may need to provide
JPU> your own instance of Swagger2Customizer [3], [4] which allows to
JPU> transform the OpenAPI/Swagger on the fly. Please let me know if that
would it work for you, thank you.

JPU> [1]
JPU> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/DynamicF
JPU> eature.html
JPU> [2]
JPU> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born-
JPU> equal.html
JPU> [3]
JPU> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger/
JPU> Swagger2Customizer.html [4]
JPU> https://cxf.apache.org/docs/swagger2feature.html (has customizer
JPU> property)


JPU> Best Regards,
JPU>     Andriy Redko

>> Hi Andriy,
>> I am again getting into trouble with server endpoint declarations.
>> Now because I am adding additional JAX-RS endpoints.
>> The issue is with:
>> 1.      The 'address' attribute on the <jaxrs:server> declaration in
>> combination with
>> 2.      The 'url-pattern' for the CXFServlet declaration in the web.xml
>> in
>> combination with
>> 3.      The @Path declaration in the interface class in combination with
>> 4.      The @Path declaration on the interface method in combination with
>> So what I had is that my web application deployed under baseUlr 'op'
>> had one JAXRS server endpoint with declarations like:
>> 1.      <jaxrs:server id="restServer"
>> basePackages="be.dvtm.aeo.op.sodexo"
>> address="/">
>> 2.      <url-pattern>/services/*</url-pattern>
>> 3.      @Path("accounts") on the public interface class
>> 4.      @Path("/{authorisationId}/customerFund") on the customerFund
>> interface method
>> A valid API call would thus be e.g.:
>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/cust
>> o
>> merFund
>> And this works correctly.
>> We're now introducing additional JAX-RS service endpoints and now I
>> am running into problems. This second endpoint was declared with:
>> 1.      <jaxrs:server id="resourceServer"
>> basePackages="be.dvtm.aeo.op.resources" address="/">
>> 2.      <url-pattern>/services/*</url-pattern>
>> 3.      @Path("resources") on the public interface class
>> 4.      @Path("/NACE") on the NACE interface method
>> So here a valid API call woud be:
>> https://<hostname>:<port>/op/services/resources/NACE.
>> The problem is that I can not declare two <jaxrs:server> entries with
>> the same ‘address’ as it throws the exception:
>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:
>> There is an endpoint already running on /.
>>  So I tried changing the addresses to:
>> ·       address=”accounts” for the restServer
>> ·       address=”resources” for the resourceServer
>> But to keep the API-call URLs the same I removed the @Path
>> declaration on the interface classes. By doing so the <jaxrs:server>
>> bean declarations no longer loads successfully.
>> So I tried to keep the @Path declaration on the interface classes but
>> changed them to @Path(“”). That does seems to work except the swagger
>> stuff no longer correctly works.

>> So what is the decent way to setup multiple JAX-RS server endpoints
>> where each server has its own configuration regarding supported features:
>> ·       own validation
>> ·       own object and exception mappings
>> ·       own swagger file generation
>> ·       own logging (in separate file if possible)
>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in
>> cooperation with swager-ui v4.5.0.
>> Below the declarations of my endpoints <<...>> Thanks for any advice.
>> Regards,
>> J.P. Urkens

>> -----Original Message-----
>> From: Andriy Redko <dr...@gmail.com>
>> Sent: zaterdag 18 juni 2022 1:12
>> To: Jean Pierre URKENS <je...@devoteam.com>;
>> issues@cxf.apache.org; dev@cxf.apache.org
>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,
>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'
>> Correct, so in the relative form like address="/<something>", the
>> JAX-RS endpoint path would be:
>>     <baseUrl>/<servlet path
>> mapping>/<address>/[@ApplicationPath]/[@Path]
>> The @ApplicationPath is optional in this case.
>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>> The JAX-WS is very different from JAX-RS, essentially the action
>> comes inside the SOAP message behind <baseUrl>/<servlet path
>> mapping>/ (@Path / @ApplicationPath are not relevant there).

>>> Question: Because now address="/" is set for the jaxrs:server will
>>> it also inspect requests targeted for the jaxws service as those
>>> requests have start with the same path '/<basePath>/services/...
>> This is a good question, I have not done it myself but I think it
>> should
>> work:
>> the servlet dispatches according to registered services, in this
>> regard JAX-RS and JAX-WS should not conflict. Does it work in your
>> case? Thank you.
>> Best Regards,
>>     Andriy Redko
>>> Hi Andriy,
>>> Using address="/" seems to work but still I don't understand how the
>>> following work together:
>>>  - path specification in servlet mapping for the CXF servlet
>>> (org.apache.cxf.transport.servlet.CXFServlet)
>>>  - the 'address' attribute on the jaxrs:server bean declaration
>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the
>>> service API description Say I've two services with (relateive to the
>>> host) url's:
>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'
>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>>> How do I configure above 3 aspects? Currently I have (working):
>>> 1.for the jaxrs:server endpoint:
>>>         - servlet path mapping: '/services/*'
>>>                - jaxrs-server address attribute: address="/"
>>>                - @Path annotation: @Path("service1") 2.For the jaxws
>>> service endpoint:
>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS
>>> requests are handleb by the same CXF servle)
>>>                - jaxws:endpoint server address attribute:
>>> address="/service2"
>>>                - @WebService(name="service2") A correct request for
>>> '1' would be '/basePath>/services/service1/<ID>'.
>>> A correct request for '2' would be '/basePath>/services/service2'.
>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:
>>>         - the server address attribute
>>>         - The API annotation (@Path or @Webservice) The JAXWS server
>>> address attribute doesn't seem to interfere with the @Webservice
>>> annotation. While the jaxrs server address attribute does seem to
>>> interfere with the @Path annotation. I would have expected the jaxrs
>>> server aspects to be configured as:
>>>         - servlet path mapping: '/services/*'
>>>                - jaxrs-server address attribute: address="/service1"
>>>                - @Path annotation: @Path("service1") but then a
>>> valid request would be
>>>> /services/service1/service1/<ID>'.
>>> For both the 'address' attribute is relative to the servlet path.
>>> The @Path Javadoc mentions that this path is relative to the
>>> ApplicationPath which thus seems to be relative to the jaxrs-server
>>> address attribute. As for @Webservice it doesnn't seem to be
>>> url-path related.
>>> Question: Because now address="/" is set for the jaxrs:server will
>>> it also inspect requests targeted for the jaxws service as those
>>> requests have start with the same path '/<basePath>/services/...'.
>>> Albeit somewhat confusing.
>>> J.P.
>>> -----Original Message-----
>>> From: Andriy Redko <dr...@gmail.com>
>>> Sent: dinsdag 14 juni 2022 1:08
>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>>> issues@cxf.apache.org; dev@cxf.apache.org
>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,
>>> Indeed, the jaxrs:server does not expect address to be omitted, you
>>> could use the "/" (and I believe an empty string would also make it):
>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...
>>> </jaxrs:server>

>>> Thank you.
>>> Hope it helps.
>>> Best Regards,
>>>     Andriy Redko

>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean
>>>> declarations
>>>> like:
>>>>      <jaxrs:server id="restServer" basePackages="xxx">
>>>>            <jaxrs:serviceBeans>
>>>>                 <ref bean="TestApi" />
>>>>            </jaxrs:serviceBeans>
>>>>            <jaxrs:providers>
>>>>                 <…/>
>>>>            </jaxrs:providers>
>>>>            <jaxrs:features>
>>>>                 <… />
>>>>            </jaxrs:features>
>>>>            <jaxrs:inInterceptors>
>>>>                 <… />
>>>>            </jaxrs:inInterceptors>
>>>>            <jaxrs:outInterceptors>*
>>>>                 <**…**/>*
>>>>            </jaxrs:outInterceptors>*
>>>>      </jaxrs:server>




>>>> Here my “TestApi” bean interface is declared like:


>>>>       @Path("accounts")
>>>>        @Consumes(MediaType.*APPLICATION_JSON*)
>>>>        @Produces(MediaType.*APPLICATION_JSON*)
>>>>        public interface TestApi {
>>>>          …
>>>>        }


>>>> And CXF is triggered via a servlet configuration like:
>>>>      <servlet>
>>>>              <display-name>CXF Servlet</display-name>
>>>>              <servlet-name>CXFServlet</servlet-name>

>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servle
>>>> t
-class>>>>>
>>>>        </servlet>
>>>>        <servlet-mapping>
>>>>              <servlet-name>CXFServlet</servlet-name>
>>>>              <url-pattern>/services/*</url-pattern>
>>>>        </servlet-mapping>




>>>> Because I’ve got the @Path declaration on the interface type I’ve
>>>> omitted the address=”accounts” attribute on the jaxrs:server
>>>> declaration since otherwise I noticed that the server would be
>>>> listening to /basepath/services/ accounts/accounts/…).


>>>> Now this configuration works perfectly, only when shutting down the
>>>> application server cxf calls
>>>>         ServerImpl#destroy()


>>>> which delegates (via Obeservable) to
>>>> AbstractHTTPDestination#deactivate()
>>>> which calls
>>>> registry.removeDestination(path).
>>>> This path is null (no ‘address’ specified on jaxrs:server
>>>> declaration) and results in a NPE on the registry Map.
>>>> This causes an unclean shutdown of my server.


>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?
>>>> How does the ‘address’ attribute on the jaxrs:server declaration
>>>> correctly interact with the @Path parameter on the API interface?

Re: How to setup multiple JAXRS server endpoints

Posted by Andriy Redko <dr...@gmail.com>.
Hi Jean,

> Am I misinterpreting this statement? It sounds to me that it should work
> with 'queryConfigEnabled=true' instead of 'queryConfigEnabled=false'?

It could be a bit confusing but I will try to explain (please let me know
if it makes sense to you):

 - when 'queryConfigEnabled=false', CXF will dynamically replace the URL in SwaggerUI,
   in this respect the value won't be taken from the query string but from `url` property
   of the SwaggerUI configuration

 - when 'queryConfigEnabled=true', CXF will do nothing and just forward query parameters to
   SwaggerUI, hoping it will somehow take care of it (basically turns off the URL replacement),
   that needs custom SwaggerUI distribution

I hope it explains the behavior, please let me know if it is still misleading (so we could
improve the documentation). Thank you.

Best Regards,
    Andriy Redko

JPU> Hi andriy,

JPU> I started off with looking at this swagger but prior to that I updated
JPU> framework versions. I am now on:
JPU>          - CXF v3.5.6
JPU>          - Swagger-UI v4.14.0

JPU> I noticed things changed with respect to the Swagger2Feature and
JPU> SwaggerUiConfig due to https://issues.apache.org/jira/browse/CXF-8636.

JPU> When reading
JPU> https://cwiki.apache.org/confluence/display/CXF20DOC/Swagger2Feature#Swagger2Feature-ConfiguringSwaggerUI(3.2.7+)
JPU> I
JPU> reconfigured the usage of the swagger features as:

JPU>         <!-- CXF Swagger2Feature -->
JPU>         <bean id="SwaggerUiConfig"
JPU> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">
JPU>                 <property name="queryConfigEnabled" value="true"/>
JPU>                 <property name="url" value="swagger.yaml"/>
JPU>         </bean>
JPU>         <bean id="swagger2Feature"
JPU> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">
JPU>                 <property name="supportSwaggerUi" value="true" />
JPU>                 <property name="swaggerUiConfig" ref="SwaggerUiConfig"/>
JPU>         </bean>

JPU> With this configuration:
JPU> * Retrieving the swagger.yaml specification works with the url:
JPU> http://l-p53-008:8082/idp/rest-services/swagger.yaml ('idp' is the war
JPU> rootpath and 'rest-services' is the CXF-servlet path)
JPU> * Loading the Swagger UI with the url:
JPU> http://l-p53-008:8082/idp/rest-services/api-docs?url=swagger.yaml FAILS ? It
JPU> loads the petshop store yaml specification.

JPU> When I change above configuration to:

JPU>         <!-- CXF Swagger2Feature -->
JPU>         <bean id="SwaggerUiConfig"
JPU> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">
JPU>                 <property name="queryConfigEnabled" value="false"/>
JPU>                 <property name="url" value="swagger.yaml"/>
JPU>         </bean>
JPU>         <bean id="swagger2Feature"
JPU> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">
JPU>                 <property name="supportSwaggerUi" value="true" />
JPU>                 <property name="swaggerUiConfig" ref="SwaggerUiConfig"/>
JPU>         </bean>

JPU> Then:
JPU> * Retrieving the swagger.yaml specification works with the url:
JPU> http://l-p53-008:8082/idp/rest-services/swagger.yaml ('idp' is the war
JPU> rootpath and 'rest-services' is the CXF-servlet path)
JPU> * Loading the Swagger UI with the url:
JPU> http://l-p53-008:8082/idp/rest-services/api-docs?url=swagger.yaml SUCCEEDS ?
JPU> It loads the swagger.yaml specification.


JPU> The confluence WIKI page above specifically mentions:
JPU> "Apache CXF prior to 3.4.6 / 3.5.1 passed Swagger UI configuration (url,
JPU> ...) as query parameters. Starting from Swagger UI 4.1.3, most of query
JPU> parameters are not accepted anymore (due to security concerns), and Apache
JPU> CXF employes different strategy and tries to replace the URL dynamically
JPU> (inside HTML) when serving Swagger UI's front web page. This behaviour could
JPU> be turned on by setting queryConfigEnabled  property of the SwaggerUiConfig
JPU> to true (the default value is false )."

JPU> Am I misinterpreting this statement? It sounds to me that it should work
JPU> with 'queryConfigEnabled=true' instead of 'queryConfigEnabled=false'?



JPU> -----Original Message-----
JPU> From: Jean Pierre URKENS <je...@devoteam.com>
JPU> Sent: dinsdag 9 mei 2023 9:25
JPU> To: 'Andriy Redko' <dr...@gmail.com>
JPU> Subject: RE: How to setup multiple JAXRS server endpoints

JPU> Hi Andriy,

JPU> Both servers have not only differences in 'authorization' but also in
JPU> exception handling regarding mapping and validation errors that's why I
JPU> can't use the same JAX-RS server bean for them. I'll have a look at
JPU> customizing the swagger feature and will come back on it but for now getting
JPU> the server up-and-running is more important.

JPU> Regards,

JPU> J.P. Urkens

JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: maandag 8 mei 2023 23:15
JPU> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev List
JPU> <de...@cxf.apache.org>
JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

JPU> Indeed the way you would like to do that is somewhat tricky.

>> So I tried to keep the @Path declaration on the interface classes but
>> changed them to @Path(“”). That does seems to work except the swagger
>> stuff no longer correctly works.

JPU> This is one of the possible options but OpenAPI/Swagger gets confused for a
JPU> reason: the path is now implicit (not in the spec).
JPU> So how about this option:
JPU>  - use only one JAX-RS server (address "/")
JPU>  - host both resources but use @Path("accounts") and @Path("resources") on
JPU> them respectively

JPU> I see that for @Path("accounts") you need to apply the
JPU> "kmopApiAuthorizationFilter", that could be done using DynamicFeature [1],
JPU> [2]. If this is not the option and you would prefer to use 2 separate JAX-RS
JPU> servers, you may need to provide your own instance of Swagger2Customizer
JPU> [3], [4] which allows to transform the OpenAPI/Swagger on the fly. Please
JPU> let me know if that would it work for you, thank you.

JPU> [1]
JPU> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/DynamicFeature.html
JPU> [2]
JPU> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born-equal.html
JPU> [3]
JPU> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger/Swagger2Customizer.html
JPU> [4] https://cxf.apache.org/docs/swagger2feature.html (has customizer
JPU> property)


JPU> Best Regards,
JPU>     Andriy Redko

>> Hi Andriy,
>> I am again getting into trouble with server endpoint declarations. Now
>> because I am adding additional JAX-RS endpoints.
>> The issue is with:
>> 1.      The 'address' attribute on the <jaxrs:server> declaration in
>> combination with
>> 2.      The 'url-pattern' for the CXFServlet declaration in the web.xml in
>> combination with
>> 3.      The @Path declaration in the interface class in combination with
>> 4.      The @Path declaration on the interface method in combination with
>> So what I had is that my web application deployed under baseUlr 'op' had
>> one JAXRS server endpoint with declarations like:
>> 1.      <jaxrs:server id="restServer" basePackages="be.dvtm.aeo.op.sodexo"
>> address="/">
>> 2.      <url-pattern>/services/*</url-pattern>
>> 3.      @Path("accounts") on the public interface class
>> 4.      @Path("/{authorisationId}/customerFund") on the customerFund
>> interface method
>> A valid API call would thus be e.g.:
>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/custo
>> merFund
>> And this works correctly.
>> We're now introducing additional JAX-RS service endpoints and now I am
>> running into problems. This second endpoint was declared with:
>> 1.      <jaxrs:server id="resourceServer"
>> basePackages="be.dvtm.aeo.op.resources" address="/">
>> 2.      <url-pattern>/services/*</url-pattern>
>> 3.      @Path("resources") on the public interface class
>> 4.      @Path("/NACE") on the NACE interface method
>> So here a valid API call woud be:
>> https://<hostname>:<port>/op/services/resources/NACE.
>> The problem is that I can not declare two <jaxrs:server> entries with the
>> same ‘address’ as it throws the exception:
>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:
>> There is an endpoint already running on /.
>>  So I tried changing the addresses to:
>> ·       address=”accounts” for the restServer
>> ·       address=”resources” for the resourceServer
>> But to keep the API-call URLs the same I removed the @Path declaration on
>> the interface classes. By doing so the <jaxrs:server> bean declarations no
>> longer loads successfully.
>> So I tried to keep the @Path declaration on the interface classes but
>> changed them to @Path(“”). That does seems to work except the swagger
>> stuff no longer correctly works.

>> So what is the decent way to setup multiple JAX-RS server endpoints where
>> each server has its own configuration regarding supported features:
>> ·       own validation
>> ·       own object and exception mappings
>> ·       own swagger file generation
>> ·       own logging (in separate file if possible)
>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in cooperation
>> with swager-ui v4.5.0.
>> Below the declarations of my endpoints <<...>> Thanks for any advice.
>> Regards,
>> J.P. Urkens

>> -----Original Message-----
>> From: Andriy Redko <dr...@gmail.com>
>> Sent: zaterdag 18 juni 2022 1:12
>> To: Jean Pierre URKENS <je...@devoteam.com>;
>> issues@cxf.apache.org; dev@cxf.apache.org
>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,
>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'
>> Correct, so in the relative form like address="/<something>", the JAX-RS
>> endpoint path would be:
>>     <baseUrl>/<servlet path
>> mapping>/<address>/[@ApplicationPath]/[@Path]
>> The @ApplicationPath is optional in this case.
>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>> The JAX-WS is very different from JAX-RS, essentially the action comes
>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/ (@Path /
>> @ApplicationPath are not relevant there).

>>> Question: Because now address="/" is set for the jaxrs:server will it
>>> also inspect requests targeted for the jaxws service as those
>>> requests have start with the same path '/<basePath>/services/...
>> This is a good question, I have not done it myself but I think it should
>> work:
>> the servlet dispatches according to registered services, in this regard
>> JAX-RS and JAX-WS should not conflict. Does it work in your case? Thank
>> you.
>> Best Regards,
>>     Andriy Redko
>>> Hi Andriy,
>>> Using address="/" seems to work but still I don't understand how the
>>> following work together:
>>>  - path specification in servlet mapping for the CXF servlet
>>> (org.apache.cxf.transport.servlet.CXFServlet)
>>>  - the 'address' attribute on the jaxrs:server bean declaration
>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the
>>> service API description Say I've two services with (relateive to the
>>> host) url's:
>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'
>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>>> How do I configure above 3 aspects? Currently I have (working):
>>> 1.for the jaxrs:server endpoint:
>>>         - servlet path mapping: '/services/*'
>>>                - jaxrs-server address attribute: address="/"
>>>                - @Path annotation: @Path("service1") 2.For the jaxws
>>> service endpoint:
>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS
>>> requests are handleb by the same CXF servle)
>>>                - jaxws:endpoint server address attribute:
>>> address="/service2"
>>>                - @WebService(name="service2") A correct request for
>>> '1' would be '/basePath>/services/service1/<ID>'.
>>> A correct request for '2' would be '/basePath>/services/service2'.
>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:
>>>         - the server address attribute
>>>         - The API annotation (@Path or @Webservice) The JAXWS server
>>> address attribute doesn't seem to interfere with the @Webservice
>>> annotation. While the jaxrs server address attribute does seem to
>>> interfere with the @Path annotation. I would have expected the jaxrs
>>> server aspects to be configured as:
>>>         - servlet path mapping: '/services/*'
>>>                - jaxrs-server address attribute: address="/service1"
>>>                - @Path annotation: @Path("service1") but then a valid
>>> request would be
>>>> /services/service1/service1/<ID>'.
>>> For both the 'address' attribute is relative to the servlet path.
>>> The @Path Javadoc mentions that this path is relative to the
>>> ApplicationPath which thus seems to be relative to the jaxrs-server
>>> address attribute. As for @Webservice it doesnn't seem to be url-path
>>> related.
>>> Question: Because now address="/" is set for the jaxrs:server will it
>>> also inspect requests targeted for the jaxws service as those
>>> requests have start with the same path '/<basePath>/services/...'.
>>> Albeit somewhat confusing.
>>> J.P.
>>> -----Original Message-----
>>> From: Andriy Redko <dr...@gmail.com>
>>> Sent: dinsdag 14 juni 2022 1:08
>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>>> issues@cxf.apache.org; dev@cxf.apache.org
>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,
>>> Indeed, the jaxrs:server does not expect address to be omitted, you
>>> could use the "/" (and I believe an empty string would also make it):
>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...
>>> </jaxrs:server>

>>> Thank you.
>>> Hope it helps.
>>> Best Regards,
>>>     Andriy Redko

>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean
>>>> declarations
>>>> like:
>>>>      <jaxrs:server id="restServer" basePackages="xxx">
>>>>            <jaxrs:serviceBeans>
>>>>                 <ref bean="TestApi" />
>>>>            </jaxrs:serviceBeans>
>>>>            <jaxrs:providers>
>>>>                 <…/>
>>>>            </jaxrs:providers>
>>>>            <jaxrs:features>
>>>>                 <… />
>>>>            </jaxrs:features>
>>>>            <jaxrs:inInterceptors>
>>>>                 <… />
>>>>            </jaxrs:inInterceptors>
>>>>            <jaxrs:outInterceptors>*
>>>>                 <**…**/>*
>>>>            </jaxrs:outInterceptors>*
>>>>      </jaxrs:server>




>>>> Here my “TestApi” bean interface is declared like:


>>>>       @Path("accounts")
>>>>        @Consumes(MediaType.*APPLICATION_JSON*)
>>>>        @Produces(MediaType.*APPLICATION_JSON*)
>>>>        public interface TestApi {
>>>>          …
>>>>        }


>>>> And CXF is triggered via a servlet configuration like:
>>>>      <servlet>
>>>>              <display-name>CXF Servlet</display-name>
>>>>              <servlet-name>CXFServlet</servlet-name>

>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servle
>>>> t
-class>>>>>
>>>>        </servlet>
>>>>        <servlet-mapping>
>>>>              <servlet-name>CXFServlet</servlet-name>
>>>>              <url-pattern>/services/*</url-pattern>
>>>>        </servlet-mapping>




>>>> Because I’ve got the @Path declaration on the interface type I’ve
>>>> omitted
>>>> the address=”accounts” attribute on the jaxrs:server declaration
>>>> since otherwise
>>>> I noticed that the server would be listening to
>>>> /basepath/services/ accounts/accounts/…).


>>>> Now this configuration works perfectly, only when shutting down
>>>> the application server cxf calls
>>>>         ServerImpl#destroy()


>>>> which delegates (via Obeservable) to
>>>> AbstractHTTPDestination#deactivate()
>>>> which calls
>>>> registry.removeDestination(path).
>>>> This path is null (no ‘address’ specified on jaxrs:server
>>>> declaration) and results in a NPE on the registry Map.
>>>> This causes an unclean shutdown of my server.


>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?
>>>> How does the ‘address’ attribute on the jaxrs:server declaration
>>>> correctly interact with the @Path parameter on the API interface?


RE: Mismatch in content encoding between client and server

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
Hi Andriy,

No problem, I am already happy to get a reply!

I am fairly new to using CXF so I learn as I go along, with all the mistakes
included.
It looks like you're right about the incorrect use of the 'content-encoding'
header. I wasn't aware about the additional setting on the MediaType so I'll
adjust that.

Best regard,

J.P.


-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: dinsdag 16 mei 2023 14:52
To: Jean Pierre URKENS <je...@devoteam.com>; dev@cxf.apache.org
Subject: Re: Mismatch in content encoding between client and server

Hi Jean,

My apologies for late response but it seems like you have found the issue
:-). However am a bit surprised by the way you are using Content-Encoding
[1]. I would expect the charset to be passed along with content type:

    Response
         .status(Status.OK)
         .entity(dvlInfo)
         .type(MediaType.APPLICATION_JSON_TYPE.withCharset("UTF-8"))
         .build();

But not as Content-Encoding header which seems to be not strictly correct
usage [2].
Hope it makes sense, thank you.

[1]
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
[2]
https://stackoverflow.com/questions/17154967/is-content-encoding-being-set-to-utf-8-invalid

Best Regards,
    Andriy Redko


JPU> Hi andriy,

JPU> As far as I could trace this the problem seems to be with the
JPU> logging of the incoming response message only.

JPU> In the method HttpConduit#handleResponseInternal the inMessage has:

JPU>
JPU> org.apache.cxf.message.Message.PROTOCOL_HEADERS={content-encoding=[
JPU> UTF-8], Content-Length=[841], content-type=[application/json],
JPU> Date=[Tue, 16 May
JPU> 2023 10:23:41 GMT], Server=[Jetty(9.4.46.v20220331)]}

JPU> But the call to "updateResponseHeaders(inMessage)" only examines
JPU> the 'content-type' protocol header not the 'content-encoding'
JPU> header. So the inMessage will not have set the
JPU> 'Message.CONTENT_TYPE' as a result the subsequent line of code (line
1682):

JPU>         String charset =
JPU> HttpHeaderHelper.findCharset((String)inMessage.get(Message.CONTENT_
JPU> TYPE));

JPU> returns 'null' resulting in normalizedEncoding=ISO-8859-1.


JPU> Is this a bug?

JPU> J.P.

JPU> -----Original Message-----
JPU> From: Jean Pierre URKENS <je...@devoteam.com>
JPU> Sent: maandag 15 mei 2023 16:46
JPU> To: 'Andriy Redko' <dr...@gmail.com>
JPU> Subject: Mismatch in content encoding between client and server

JPU> Hi Andriy,

JPU> I got my services installed but when performing some local (JUnit)
JPU> tests I notice that I am losing the content-encoding.

JPU> E.g. in below message logging from CXF the country 'België' is
JPU> passed in the response which has the header content-encoding=UTF-8 set.
JPU> When reading/parsing the response it results in ' België' ?

JPU> What does the server/client need to do to make sure the content is
JPU> correctly encoded/decoded when:
JPU>  - the server writes the result entity in the reponse  (I used
JPU> "Response.status(Status.OK).entity(dvlInfo).type(MediaType.APPLICAT
JPU> ION_JSON).encoding("UTF-8").build()")
JPU>  - the client reads the result entity from the response (I didn't
JPU> directly see anything to inform the reader that the content is
JPU> UTF-8 encoded so it is currently read by the client as
JPU> "resp.readEntity(Dienstverlener.class)")


JPU> Below the CXF message logging:

JPU> KMOP] 2023-05-15 16:29:38,503 [main] INFO  $--$
JPU> (org.slf4j.helpers.MarkerIgnoringBase:95) - REQ_OUT
JPU>     Address:
JPU>
http://localhost:8185/op/services/dienstverlener/dienstverlener/findErkendByErkNr?erkNr=DV.O235055
JPU>     HttpMethod: GET
JPU>     Content-Type: application/json
JPU>     ExchangeId: 569ef415-99f7-41c2-956e-38e47ea8e4e5
JPU>     Headers: {Accept=application/json,
JPU> X-KMO-OPERATION-ID=ceaa4c95-0677-4510-b574-d99d82a45545,
JPU> Content-Type=application/json}

JPU> [KMOP] 2023-05-15 16:29:38,745 [qtp1348937989-29] INFO  $--$
JPU> (org.slf4j.helpers.MarkerIgnoringBase:95) - REQ_IN
JPU>     Address:
JPU>
http://localhost:8185/op/services/dienstverlener/dienstverlener/findErkendByErkNr?erkNr=DV.O235055
JPU>     HttpMethod: GET
JPU>     Content-Type: application/json
JPU>     ExchangeId: 0c78ff64-8016-4809-adf8-691d786d0dfd
JPU>     Headers: {Accept=application/json, Cache-Control=no-cache,
JPU> User-Agent=Apache-CXF/3.5.2,
JPU> X-KMO-OPERATION-ID=ceaa4c95-0677-4510-b574-d99d82a45545,
JPU> connection=keep-alive, content-type=application/json,
JPU> Host=localhost:8185, Pragma=no-cache}

JPU> [KMOP] 2023-05-15 16:29:38,751 [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBPoolManager:192) - Getting DBase connection
JPU> from DBPoolManager for DataSource name=DEFAULT_DS [KMOP] 2023-05-15
JPU> 16:29:38,752 [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBPoolManager:195) - Found
JPU> DataSource=oracle.jdbc.pool.OracleDataSource@77be656f for
JPU> DataSource name=DEFAULT_DS [KMOP] 2023-05-15 16:29:39,091
JPU> [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBPoolManager:202) - Obtained DBase
JPU> connection(1995619431,autoCommit=true) from datasource DEFAULT_DS
JPU> in
JPU> 338.9987 milliseconds.
JPU> [KMOP] 2023-05-15 16:29:39,346 [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBHelper:386) - executed SQL-query
JPU> 'selDvlInfoForMMByErkNrAsJson' : obtained DBase resultset in
JPU> 190.5721 milliseconds.
JPU> [KMOP] 2023-05-15 16:29:39,352 [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBHelper:395) - executed SQL-query
JPU> 'selDvlInfoForMMByErkNrAsJson' : processed DBase resultset (1st
JPU> record) in
JPU> 5.4814 milliseconds.
JPU> [KMOP] 2023-05-15 16:29:39,352 [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBHelper:433) - Closing DBase
JPU> connection(1995619431,autoCommit=true)
JPU> [KMOP] 2023-05-15 16:29:39,391 [qtp1348937989-29] INFO  $--$
JPU> (org.slf4j.helpers.MarkerIgnoringBase:95) - RESP_OUT
JPU>     Address:
JPU>
http://localhost:8185/op/services/dienstverlener/dienstverlener/findErkendByErkNr?erkNr=DV.O235055
JPU>     Content-Type: application/json
JPU>     ResponseCode: 200
JPU>     ExchangeId: 0c78ff64-8016-4809-adf8-691d786d0dfd
JPU>     Headers: {Content-Encoding=UTF-8, Date=Mon, 15 May 2023
JPU> 14:29:39 GMT, Content-Type=application/json}
JPU>     Payload: {"id":325943,"naam":"Qrios campus
JPU> Aarschot","MZnaam":"QRIOS vzw
JPU> ","kboNr":"0422695514","erkenningen":[{"dienst":"opleiding","nummer
JPU> ":"DV.O235055","erkendTot":"9999-01-01"}],"themas":[100000,100002,1
JPU> 00010,100011,102290,102291,102292],"beoordelingen":[{"dienst":"ople
JPU> iding","aantalBeoordelingen":10,"score":4.5}],"adres":{"land":"Belg
JPU> ië","postcode":"3200","gemeente":"Aarschot","straat":"Bekaflaan","h
JPU> uisNummer":"62","busNummer":null},"contact":{"contactPersoon":"Pete
JPU> r
JPU> Holsters","telNr":"003216551115","faxNr":null,"email":"aarschot@qri
JPU> os.be","website":"http://www.qrios.be"},"beschrijving":"Opleidingsv
JPU> erstrekker
JPU> opleidingen voor
JPU> volwassenen","banner":"http://AEODEV.BE.DEVOTEAM.COM:8081/images/op
JPU> /dvl/banner_325943.png","logo":"http://AEODEV.BE.DEVOTEAM.COM:8081/
JPU> images/op/dvl/logo_325943.png","latitude":50.98734451,"longitude":4
JPU> .8472477}

JPU> [KMOP] 2023-05-15 16:29:39,399 [main] INFO  $--$
JPU> (org.slf4j.helpers.MarkerIgnoringBase:95) - RESP_IN
JPU>     Address:
JPU>
http://localhost:8185/op/services/dienstverlener/dienstverlener/findErkendByErkNr?erkNr=DV.O235055
JPU>     Content-Type: application/json
JPU>     ResponseCode: 200
JPU>     ExchangeId: 569ef415-99f7-41c2-956e-38e47ea8e4e5
JPU>     Headers: {Server=Jetty(9.4.46.v20220331),
JPU> content-encoding=UTF-8, content-type=application/json,
JPU> Content-Length=841, Date=Mon, 15 May 2023
JPU> 14:29:39 GMT}
JPU>     Payload: {"id":325943,"naam":"Qrios campus
JPU> Aarschot","MZnaam":"QRIOS vzw
JPU> ","kboNr":"0422695514","erkenningen":[{"dienst":"opleiding","nummer
JPU> ":"DV.O235055","erkendTot":"9999-01-01"}],"themas":[100000,100002,1
JPU> 00010,100011,102290,102291,102292],"beoordelingen":[{"dienst":"ople
JPU> iding","aantalBeoordelingen":10,"score":4.5}],"adres":{"land":"Belg
JPU> ië","postcode":"3200","gemeente":"Aarschot","straat":"Bekaflaan","
JPU> huisNummer":"62","busNummer":null},"contact":{"contactPersoon":"Pet
JPU> er
JPU> Holsters","telNr":"003216551115","faxNr":null,"email":"aarschot@qri
JPU> os.be","website":"http://www.qrios.be"},"beschrijving":"Opleidingsv
JPU> erstrekker
JPU> opleidingen voor
JPU> volwassenen","banner":"http://AEODEV.BE.DEVOTEAM.COM:8081/images/op
JPU> /dvl/banner_325943.png","logo":"http://AEODEV.BE.DEVOTEAM.COM:8081/
JPU> images/op/dvl/logo_325943.png","latitude":50.98734451,"longitude":4
JPU> .8472477}

JPU> -----Original Message-----
JPU> From: Jean Pierre URKENS <je...@devoteam.com>
JPU> Sent: dinsdag 9 mei 2023 9:25
JPU> To: 'Andriy Redko' <dr...@gmail.com>
JPU> Subject: RE: How to setup multiple JAXRS server endpoints

JPU> Hi Andriy,

JPU> Both servers have not only differences in 'authorization' but also
JPU> in exception handling regarding mapping and validation errors
JPU> that's why I can't use the same JAX-RS server bean for them. I'll
JPU> have a look at customizing the swagger feature and will come back
JPU> on it but for now getting the server up-and-running is more important.

JPU> Regards,

JPU> J.P. Urkens

JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: maandag 8 mei 2023 23:15
JPU> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev
JPU> List <de...@cxf.apache.org>
JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

JPU> Indeed the way you would like to do that is somewhat tricky.

>> So I tried to keep the @Path declaration on the interface classes but
>> changed them to @Path(“”). That does seems to work except the swagger
>> stuff no longer correctly works.

JPU> This is one of the possible options but OpenAPI/Swagger gets
JPU> confused for a
JPU> reason: the path is now implicit (not in the spec).
JPU> So how about this option:
JPU>  - use only one JAX-RS server (address "/")
JPU>  - host both resources but use @Path("accounts") and
JPU> @Path("resources") on them respectively

JPU> I see that for @Path("accounts") you need to apply the
JPU> "kmopApiAuthorizationFilter", that could be done using
JPU> DynamicFeature [1], [2]. If this is not the option and you would
JPU> prefer to use 2 separate JAX-RS servers, you may need to provide
JPU> your own instance of Swagger2Customizer [3], [4] which allows to
JPU> transform the OpenAPI/Swagger on the fly. Please let me know if that
would it work for you, thank you.

JPU> [1]
JPU> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/DynamicF
JPU> eature.html
JPU> [2]
JPU> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born-
JPU> equal.html
JPU> [3]
JPU> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger/
JPU> Swagger2Customizer.html [4]
JPU> https://cxf.apache.org/docs/swagger2feature.html (has customizer
JPU> property)


JPU> Best Regards,
JPU>     Andriy Redko

>> Hi Andriy,
>> I am again getting into trouble with server endpoint declarations.
>> Now because I am adding additional JAX-RS endpoints.
>> The issue is with:
>> 1.      The 'address' attribute on the <jaxrs:server> declaration in
>> combination with
>> 2.      The 'url-pattern' for the CXFServlet declaration in the web.xml
>> in
>> combination with
>> 3.      The @Path declaration in the interface class in combination with
>> 4.      The @Path declaration on the interface method in combination with
>> So what I had is that my web application deployed under baseUlr 'op'
>> had one JAXRS server endpoint with declarations like:
>> 1.      <jaxrs:server id="restServer"
>> basePackages="be.dvtm.aeo.op.sodexo"
>> address="/">
>> 2.      <url-pattern>/services/*</url-pattern>
>> 3.      @Path("accounts") on the public interface class
>> 4.      @Path("/{authorisationId}/customerFund") on the customerFund
>> interface method
>> A valid API call would thus be e.g.:
>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/cust
>> o
>> merFund
>> And this works correctly.
>> We're now introducing additional JAX-RS service endpoints and now I
>> am running into problems. This second endpoint was declared with:
>> 1.      <jaxrs:server id="resourceServer"
>> basePackages="be.dvtm.aeo.op.resources" address="/">
>> 2.      <url-pattern>/services/*</url-pattern>
>> 3.      @Path("resources") on the public interface class
>> 4.      @Path("/NACE") on the NACE interface method
>> So here a valid API call woud be:
>> https://<hostname>:<port>/op/services/resources/NACE.
>> The problem is that I can not declare two <jaxrs:server> entries with
>> the same ‘address’ as it throws the exception:
>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:
>> There is an endpoint already running on /.
>>  So I tried changing the addresses to:
>> ·       address=”accounts” for the restServer
>> ·       address=”resources” for the resourceServer
>> But to keep the API-call URLs the same I removed the @Path
>> declaration on the interface classes. By doing so the <jaxrs:server>
>> bean declarations no longer loads successfully.
>> So I tried to keep the @Path declaration on the interface classes but
>> changed them to @Path(“”). That does seems to work except the swagger
>> stuff no longer correctly works.

>> So what is the decent way to setup multiple JAX-RS server endpoints
>> where each server has its own configuration regarding supported features:
>> ·       own validation
>> ·       own object and exception mappings
>> ·       own swagger file generation
>> ·       own logging (in separate file if possible)
>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in
>> cooperation with swager-ui v4.5.0.
>> Below the declarations of my endpoints <<...>> Thanks for any advice.
>> Regards,
>> J.P. Urkens

>> -----Original Message-----
>> From: Andriy Redko <dr...@gmail.com>
>> Sent: zaterdag 18 juni 2022 1:12
>> To: Jean Pierre URKENS <je...@devoteam.com>;
>> issues@cxf.apache.org; dev@cxf.apache.org
>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,
>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'
>> Correct, so in the relative form like address="/<something>", the
>> JAX-RS endpoint path would be:
>>     <baseUrl>/<servlet path
>> mapping>/<address>/[@ApplicationPath]/[@Path]
>> The @ApplicationPath is optional in this case.
>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>> The JAX-WS is very different from JAX-RS, essentially the action
>> comes inside the SOAP message behind <baseUrl>/<servlet path
>> mapping>/ (@Path / @ApplicationPath are not relevant there).

>>> Question: Because now address="/" is set for the jaxrs:server will
>>> it also inspect requests targeted for the jaxws service as those
>>> requests have start with the same path '/<basePath>/services/...
>> This is a good question, I have not done it myself but I think it
>> should
>> work:
>> the servlet dispatches according to registered services, in this
>> regard JAX-RS and JAX-WS should not conflict. Does it work in your
>> case? Thank you.
>> Best Regards,
>>     Andriy Redko
>>> Hi Andriy,
>>> Using address="/" seems to work but still I don't understand how the
>>> following work together:
>>>  - path specification in servlet mapping for the CXF servlet
>>> (org.apache.cxf.transport.servlet.CXFServlet)
>>>  - the 'address' attribute on the jaxrs:server bean declaration
>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the
>>> service API description Say I've two services with (relateive to the
>>> host) url's:
>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'
>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>>> How do I configure above 3 aspects? Currently I have (working):
>>> 1.for the jaxrs:server endpoint:
>>>         - servlet path mapping: '/services/*'
>>>                - jaxrs-server address attribute: address="/"
>>>                - @Path annotation: @Path("service1") 2.For the jaxws
>>> service endpoint:
>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS
>>> requests are handleb by the same CXF servle)
>>>                - jaxws:endpoint server address attribute:
>>> address="/service2"
>>>                - @WebService(name="service2") A correct request for
>>> '1' would be '/basePath>/services/service1/<ID>'.
>>> A correct request for '2' would be '/basePath>/services/service2'.
>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:
>>>         - the server address attribute
>>>         - The API annotation (@Path or @Webservice) The JAXWS server
>>> address attribute doesn't seem to interfere with the @Webservice
>>> annotation. While the jaxrs server address attribute does seem to
>>> interfere with the @Path annotation. I would have expected the jaxrs
>>> server aspects to be configured as:
>>>         - servlet path mapping: '/services/*'
>>>                - jaxrs-server address attribute: address="/service1"
>>>                - @Path annotation: @Path("service1") but then a
>>> valid request would be
>>>> /services/service1/service1/<ID>'.
>>> For both the 'address' attribute is relative to the servlet path.
>>> The @Path Javadoc mentions that this path is relative to the
>>> ApplicationPath which thus seems to be relative to the jaxrs-server
>>> address attribute. As for @Webservice it doesnn't seem to be
>>> url-path related.
>>> Question: Because now address="/" is set for the jaxrs:server will
>>> it also inspect requests targeted for the jaxws service as those
>>> requests have start with the same path '/<basePath>/services/...'.
>>> Albeit somewhat confusing.
>>> J.P.
>>> -----Original Message-----
>>> From: Andriy Redko <dr...@gmail.com>
>>> Sent: dinsdag 14 juni 2022 1:08
>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>>> issues@cxf.apache.org; dev@cxf.apache.org
>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,
>>> Indeed, the jaxrs:server does not expect address to be omitted, you
>>> could use the "/" (and I believe an empty string would also make it):
>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...
>>> </jaxrs:server>

>>> Thank you.
>>> Hope it helps.
>>> Best Regards,
>>>     Andriy Redko

>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean
>>>> declarations
>>>> like:
>>>>      <jaxrs:server id="restServer" basePackages="xxx">
>>>>            <jaxrs:serviceBeans>
>>>>                 <ref bean="TestApi" />
>>>>            </jaxrs:serviceBeans>
>>>>            <jaxrs:providers>
>>>>                 <…/>
>>>>            </jaxrs:providers>
>>>>            <jaxrs:features>
>>>>                 <… />
>>>>            </jaxrs:features>
>>>>            <jaxrs:inInterceptors>
>>>>                 <… />
>>>>            </jaxrs:inInterceptors>
>>>>            <jaxrs:outInterceptors>*
>>>>                 <**…**/>*
>>>>            </jaxrs:outInterceptors>*
>>>>      </jaxrs:server>




>>>> Here my “TestApi” bean interface is declared like:


>>>>       @Path("accounts")
>>>>        @Consumes(MediaType.*APPLICATION_JSON*)
>>>>        @Produces(MediaType.*APPLICATION_JSON*)
>>>>        public interface TestApi {
>>>>          …
>>>>        }


>>>> And CXF is triggered via a servlet configuration like:
>>>>      <servlet>
>>>>              <display-name>CXF Servlet</display-name>
>>>>              <servlet-name>CXFServlet</servlet-name>

>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servle
>>>> t
-class>>>>>
>>>>        </servlet>
>>>>        <servlet-mapping>
>>>>              <servlet-name>CXFServlet</servlet-name>
>>>>              <url-pattern>/services/*</url-pattern>
>>>>        </servlet-mapping>




>>>> Because I’ve got the @Path declaration on the interface type I’ve
>>>> omitted the address=”accounts” attribute on the jaxrs:server
>>>> declaration since otherwise I noticed that the server would be
>>>> listening to /basepath/services/ accounts/accounts/…).


>>>> Now this configuration works perfectly, only when shutting down the
>>>> application server cxf calls
>>>>         ServerImpl#destroy()


>>>> which delegates (via Obeservable) to
>>>> AbstractHTTPDestination#deactivate()
>>>> which calls
>>>> registry.removeDestination(path).
>>>> This path is null (no ‘address’ specified on jaxrs:server
>>>> declaration) and results in a NPE on the registry Map.
>>>> This causes an unclean shutdown of my server.


>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?
>>>> How does the ‘address’ attribute on the jaxrs:server declaration
>>>> correctly interact with the @Path parameter on the API interface?

Re: Mismatch in content encoding between client and server

Posted by Andriy Redko <dr...@gmail.com>.
Hi Jean,

My apologies for late response but it seems like you have found the issue :-). However 
am a bit surprised by the way you are using Content-Encoding [1]. I would expect the 
charset to be passed along with content type:

    Response
         .status(Status.OK)
         .entity(dvlInfo)
         .type(MediaType.APPLICATION_JSON_TYPE.withCharset("UTF-8"))
         .build();

But not as Content-Encoding header which seems to be not strictly correct usage [2].
Hope it makes sense, thank you.

[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
[2] https://stackoverflow.com/questions/17154967/is-content-encoding-being-set-to-utf-8-invalid

Best Regards,
    Andriy Redko


JPU> Hi andriy,

JPU> As far as I could trace this the problem seems to be with the logging of the
JPU> incoming response message only.

JPU> In the method HttpConduit#handleResponseInternal the inMessage has:

JPU>         org.apache.cxf.message.Message.PROTOCOL_HEADERS={content-encoding=[UTF-8],
JPU> Content-Length=[841], content-type=[application/json], Date=[Tue, 16 May
JPU> 2023 10:23:41 GMT], Server=[Jetty(9.4.46.v20220331)]}

JPU> But the call to "updateResponseHeaders(inMessage)" only examines the
JPU> 'content-type' protocol header not the 'content-encoding' header. So the
JPU> inMessage will not have set the 'Message.CONTENT_TYPE' as a result the
JPU> subsequent line of code (line 1682):

JPU>         String charset =
JPU> HttpHeaderHelper.findCharset((String)inMessage.get(Message.CONTENT_TYPE));

JPU> returns 'null' resulting in normalizedEncoding=ISO-8859-1.


JPU> Is this a bug?

JPU> J.P.

JPU> -----Original Message-----
JPU> From: Jean Pierre URKENS <je...@devoteam.com>
JPU> Sent: maandag 15 mei 2023 16:46
JPU> To: 'Andriy Redko' <dr...@gmail.com>
JPU> Subject: Mismatch in content encoding between client and server

JPU> Hi Andriy,

JPU> I got my services installed but when performing some local (JUnit) tests I
JPU> notice that I am losing the content-encoding.

JPU> E.g. in below message logging from CXF the country 'België' is passed in the
JPU> response which has the header content-encoding=UTF-8 set.
JPU> When reading/parsing the response it results in ' België' ?

JPU> What does the server/client need to do to make sure the content is correctly
JPU> encoded/decoded when:
JPU>  - the server writes the result entity in the reponse  (I used
JPU> "Response.status(Status.OK).entity(dvlInfo).type(MediaType.APPLICATION_JSON).encoding("UTF-8").build()")
JPU>  - the client reads the result entity from the response (I didn't directly
JPU> see anything to inform the reader that the content is UTF-8 encoded so it is
JPU> currently read by the client as "resp.readEntity(Dienstverlener.class)")


JPU> Below the CXF message logging:

JPU> KMOP] 2023-05-15 16:29:38,503 [main] INFO  $--$
JPU> (org.slf4j.helpers.MarkerIgnoringBase:95) - REQ_OUT
JPU>     Address:
JPU> http://localhost:8185/op/services/dienstverlener/dienstverlener/findErkendByErkNr?erkNr=DV.O235055
JPU>     HttpMethod: GET
JPU>     Content-Type: application/json
JPU>     ExchangeId: 569ef415-99f7-41c2-956e-38e47ea8e4e5
JPU>     Headers: {Accept=application/json,
JPU> X-KMO-OPERATION-ID=ceaa4c95-0677-4510-b574-d99d82a45545,
JPU> Content-Type=application/json}

JPU> [KMOP] 2023-05-15 16:29:38,745 [qtp1348937989-29] INFO  $--$
JPU> (org.slf4j.helpers.MarkerIgnoringBase:95) - REQ_IN
JPU>     Address:
JPU> http://localhost:8185/op/services/dienstverlener/dienstverlener/findErkendByErkNr?erkNr=DV.O235055
JPU>     HttpMethod: GET
JPU>     Content-Type: application/json
JPU>     ExchangeId: 0c78ff64-8016-4809-adf8-691d786d0dfd
JPU>     Headers: {Accept=application/json, Cache-Control=no-cache,
JPU> User-Agent=Apache-CXF/3.5.2,
JPU> X-KMO-OPERATION-ID=ceaa4c95-0677-4510-b574-d99d82a45545,
JPU> connection=keep-alive, content-type=application/json, Host=localhost:8185,
JPU> Pragma=no-cache}

JPU> [KMOP] 2023-05-15 16:29:38,751 [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBPoolManager:192) - Getting DBase connection from
JPU> DBPoolManager for DataSource name=DEFAULT_DS [KMOP] 2023-05-15 16:29:38,752
JPU> [qtp1348937989-29] DEBUG $--$ (be.xm.base.database.DBPoolManager:195) -
JPU> Found DataSource=oracle.jdbc.pool.OracleDataSource@77be656f for DataSource
JPU> name=DEFAULT_DS [KMOP] 2023-05-15 16:29:39,091 [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBPoolManager:202) - Obtained DBase
JPU> connection(1995619431,autoCommit=true) from datasource DEFAULT_DS in
JPU> 338.9987 milliseconds.
JPU> [KMOP] 2023-05-15 16:29:39,346 [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBHelper:386) - executed SQL-query
JPU> 'selDvlInfoForMMByErkNrAsJson' : obtained DBase resultset in 190.5721
JPU> milliseconds.
JPU> [KMOP] 2023-05-15 16:29:39,352 [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBHelper:395) - executed SQL-query
JPU> 'selDvlInfoForMMByErkNrAsJson' : processed DBase resultset (1st record) in
JPU> 5.4814 milliseconds.
JPU> [KMOP] 2023-05-15 16:29:39,352 [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBHelper:433) - Closing DBase
JPU> connection(1995619431,autoCommit=true)
JPU> [KMOP] 2023-05-15 16:29:39,391 [qtp1348937989-29] INFO  $--$
JPU> (org.slf4j.helpers.MarkerIgnoringBase:95) - RESP_OUT
JPU>     Address:
JPU> http://localhost:8185/op/services/dienstverlener/dienstverlener/findErkendByErkNr?erkNr=DV.O235055
JPU>     Content-Type: application/json
JPU>     ResponseCode: 200
JPU>     ExchangeId: 0c78ff64-8016-4809-adf8-691d786d0dfd
JPU>     Headers: {Content-Encoding=UTF-8, Date=Mon, 15 May 2023 14:29:39 GMT,
JPU> Content-Type=application/json}
JPU>     Payload: {"id":325943,"naam":"Qrios campus Aarschot","MZnaam":"QRIOS vzw
JPU> ","kboNr":"0422695514","erkenningen":[{"dienst":"opleiding","nummer":"DV.O235055","erkendTot":"9999-01-01"}],"themas":[100000,100002,100010,100011,102290,102291,102292],"beoordelingen":[{"dienst":"opleiding","aantalBeoordelingen":10,"score":4.5}],"adres":{"land":"België","postcode":"3200","gemeente":"Aarschot","straat":"Bekaflaan","huisNummer":"62","busNummer":null},"contact":{"contactPersoon":"Peter
JPU> Holsters","telNr":"003216551115","faxNr":null,"email":"aarschot@qrios.be","website":"http://www.qrios.be"},"beschrijving":"Opleidingsverstrekker
JPU> opleidingen voor
JPU> volwassenen","banner":"http://AEODEV.BE.DEVOTEAM.COM:8081/images/op/dvl/banner_325943.png","logo":"http://AEODEV.BE.DEVOTEAM.COM:8081/images/op/dvl/logo_325943.png","latitude":50.98734451,"longitude":4.8472477}

JPU> [KMOP] 2023-05-15 16:29:39,399 [main] INFO  $--$
JPU> (org.slf4j.helpers.MarkerIgnoringBase:95) - RESP_IN
JPU>     Address:
JPU> http://localhost:8185/op/services/dienstverlener/dienstverlener/findErkendByErkNr?erkNr=DV.O235055
JPU>     Content-Type: application/json
JPU>     ResponseCode: 200
JPU>     ExchangeId: 569ef415-99f7-41c2-956e-38e47ea8e4e5
JPU>     Headers: {Server=Jetty(9.4.46.v20220331), content-encoding=UTF-8,
JPU> content-type=application/json, Content-Length=841, Date=Mon, 15 May 2023
JPU> 14:29:39 GMT}
JPU>     Payload: {"id":325943,"naam":"Qrios campus Aarschot","MZnaam":"QRIOS vzw
JPU> ","kboNr":"0422695514","erkenningen":[{"dienst":"opleiding","nummer":"DV.O235055","erkendTot":"9999-01-01"}],"themas":[100000,100002,100010,100011,102290,102291,102292],"beoordelingen":[{"dienst":"opleiding","aantalBeoordelingen":10,"score":4.5}],"adres":{"land":"België","postcode":"3200","gemeente":"Aarschot","straat":"Bekaflaan","huisNummer":"62","busNummer":null},"contact":{"contactPersoon":"Peter
JPU> Holsters","telNr":"003216551115","faxNr":null,"email":"aarschot@qrios.be","website":"http://www.qrios.be"},"beschrijving":"Opleidingsverstrekker
JPU> opleidingen voor
JPU> volwassenen","banner":"http://AEODEV.BE.DEVOTEAM.COM:8081/images/op/dvl/banner_325943.png","logo":"http://AEODEV.BE.DEVOTEAM.COM:8081/images/op/dvl/logo_325943.png","latitude":50.98734451,"longitude":4.8472477}

JPU> -----Original Message-----
JPU> From: Jean Pierre URKENS <je...@devoteam.com>
JPU> Sent: dinsdag 9 mei 2023 9:25
JPU> To: 'Andriy Redko' <dr...@gmail.com>
JPU> Subject: RE: How to setup multiple JAXRS server endpoints

JPU> Hi Andriy,

JPU> Both servers have not only differences in 'authorization' but also in
JPU> exception handling regarding mapping and validation errors that's why I
JPU> can't use the same JAX-RS server bean for them. I'll have a look at
JPU> customizing the swagger feature and will come back on it but for now getting
JPU> the server up-and-running is more important.

JPU> Regards,

JPU> J.P. Urkens

JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: maandag 8 mei 2023 23:15
JPU> To: Jean Pierre URKENS <je...@devoteam.com>; CXF Dev List
JPU> <de...@cxf.apache.org>
JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

JPU> Indeed the way you would like to do that is somewhat tricky.

>> So I tried to keep the @Path declaration on the interface classes but
>> changed them to @Path(“”). That does seems to work except the swagger
>> stuff no longer correctly works.

JPU> This is one of the possible options but OpenAPI/Swagger gets confused for a
JPU> reason: the path is now implicit (not in the spec).
JPU> So how about this option:
JPU>  - use only one JAX-RS server (address "/")
JPU>  - host both resources but use @Path("accounts") and @Path("resources") on
JPU> them respectively

JPU> I see that for @Path("accounts") you need to apply the
JPU> "kmopApiAuthorizationFilter", that could be done using DynamicFeature [1],
JPU> [2]. If this is not the option and you would prefer to use 2 separate JAX-RS
JPU> servers, you may need to provide your own instance of Swagger2Customizer
JPU> [3], [4] which allows to transform the OpenAPI/Swagger on the fly. Please
JPU> let me know if that would it work for you, thank you.

JPU> [1]
JPU> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/DynamicFeature.html
JPU> [2]
JPU> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born-equal.html
JPU> [3]
JPU> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger/Swagger2Customizer.html
JPU> [4] https://cxf.apache.org/docs/swagger2feature.html (has customizer
JPU> property)


JPU> Best Regards,
JPU>     Andriy Redko

>> Hi Andriy,
>> I am again getting into trouble with server endpoint declarations. Now
>> because I am adding additional JAX-RS endpoints.
>> The issue is with:
>> 1.      The 'address' attribute on the <jaxrs:server> declaration in
>> combination with
>> 2.      The 'url-pattern' for the CXFServlet declaration in the web.xml in
>> combination with
>> 3.      The @Path declaration in the interface class in combination with
>> 4.      The @Path declaration on the interface method in combination with
>> So what I had is that my web application deployed under baseUlr 'op' had
>> one JAXRS server endpoint with declarations like:
>> 1.      <jaxrs:server id="restServer" basePackages="be.dvtm.aeo.op.sodexo"
>> address="/">
>> 2.      <url-pattern>/services/*</url-pattern>
>> 3.      @Path("accounts") on the public interface class
>> 4.      @Path("/{authorisationId}/customerFund") on the customerFund
>> interface method
>> A valid API call would thus be e.g.:
>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/custo
>> merFund
>> And this works correctly.
>> We're now introducing additional JAX-RS service endpoints and now I am
>> running into problems. This second endpoint was declared with:
>> 1.      <jaxrs:server id="resourceServer"
>> basePackages="be.dvtm.aeo.op.resources" address="/">
>> 2.      <url-pattern>/services/*</url-pattern>
>> 3.      @Path("resources") on the public interface class
>> 4.      @Path("/NACE") on the NACE interface method
>> So here a valid API call woud be:
>> https://<hostname>:<port>/op/services/resources/NACE.
>> The problem is that I can not declare two <jaxrs:server> entries with the
>> same ‘address’ as it throws the exception:
>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:
>> There is an endpoint already running on /.
>>  So I tried changing the addresses to:
>> ·       address=”accounts” for the restServer
>> ·       address=”resources” for the resourceServer
>> But to keep the API-call URLs the same I removed the @Path declaration on
>> the interface classes. By doing so the <jaxrs:server> bean declarations no
>> longer loads successfully.
>> So I tried to keep the @Path declaration on the interface classes but
>> changed them to @Path(“”). That does seems to work except the swagger
>> stuff no longer correctly works.

>> So what is the decent way to setup multiple JAX-RS server endpoints where
>> each server has its own configuration regarding supported features:
>> ·       own validation
>> ·       own object and exception mappings
>> ·       own swagger file generation
>> ·       own logging (in separate file if possible)
>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in cooperation
>> with swager-ui v4.5.0.
>> Below the declarations of my endpoints <<...>> Thanks for any advice.
>> Regards,
>> J.P. Urkens

>> -----Original Message-----
>> From: Andriy Redko <dr...@gmail.com>
>> Sent: zaterdag 18 juni 2022 1:12
>> To: Jean Pierre URKENS <je...@devoteam.com>;
>> issues@cxf.apache.org; dev@cxf.apache.org
>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,
>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'
>> Correct, so in the relative form like address="/<something>", the JAX-RS
>> endpoint path would be:
>>     <baseUrl>/<servlet path
>> mapping>/<address>/[@ApplicationPath]/[@Path]
>> The @ApplicationPath is optional in this case.
>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>> The JAX-WS is very different from JAX-RS, essentially the action comes
>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/ (@Path /
>> @ApplicationPath are not relevant there).

>>> Question: Because now address="/" is set for the jaxrs:server will it
>>> also inspect requests targeted for the jaxws service as those
>>> requests have start with the same path '/<basePath>/services/...
>> This is a good question, I have not done it myself but I think it should
>> work:
>> the servlet dispatches according to registered services, in this regard
>> JAX-RS and JAX-WS should not conflict. Does it work in your case? Thank
>> you.
>> Best Regards,
>>     Andriy Redko
>>> Hi Andriy,
>>> Using address="/" seems to work but still I don't understand how the
>>> following work together:
>>>  - path specification in servlet mapping for the CXF servlet
>>> (org.apache.cxf.transport.servlet.CXFServlet)
>>>  - the 'address' attribute on the jaxrs:server bean declaration
>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the
>>> service API description Say I've two services with (relateive to the
>>> host) url's:
>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'
>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>>> How do I configure above 3 aspects? Currently I have (working):
>>> 1.for the jaxrs:server endpoint:
>>>         - servlet path mapping: '/services/*'
>>>                - jaxrs-server address attribute: address="/"
>>>                - @Path annotation: @Path("service1") 2.For the jaxws
>>> service endpoint:
>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS
>>> requests are handleb by the same CXF servle)
>>>                - jaxws:endpoint server address attribute:
>>> address="/service2"
>>>                - @WebService(name="service2") A correct request for
>>> '1' would be '/basePath>/services/service1/<ID>'.
>>> A correct request for '2' would be '/basePath>/services/service2'.
>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:
>>>         - the server address attribute
>>>         - The API annotation (@Path or @Webservice) The JAXWS server
>>> address attribute doesn't seem to interfere with the @Webservice
>>> annotation. While the jaxrs server address attribute does seem to
>>> interfere with the @Path annotation. I would have expected the jaxrs
>>> server aspects to be configured as:
>>>         - servlet path mapping: '/services/*'
>>>                - jaxrs-server address attribute: address="/service1"
>>>                - @Path annotation: @Path("service1") but then a valid
>>> request would be
>>>> /services/service1/service1/<ID>'.
>>> For both the 'address' attribute is relative to the servlet path.
>>> The @Path Javadoc mentions that this path is relative to the
>>> ApplicationPath which thus seems to be relative to the jaxrs-server
>>> address attribute. As for @Webservice it doesnn't seem to be url-path
>>> related.
>>> Question: Because now address="/" is set for the jaxrs:server will it
>>> also inspect requests targeted for the jaxws service as those
>>> requests have start with the same path '/<basePath>/services/...'.
>>> Albeit somewhat confusing.
>>> J.P.
>>> -----Original Message-----
>>> From: Andriy Redko <dr...@gmail.com>
>>> Sent: dinsdag 14 juni 2022 1:08
>>> To: Jean Pierre URKENS <je...@devoteam.com>;
>>> issues@cxf.apache.org; dev@cxf.apache.org
>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,
>>> Indeed, the jaxrs:server does not expect address to be omitted, you
>>> could use the "/" (and I believe an empty string would also make it):
>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...
>>> </jaxrs:server>

>>> Thank you.
>>> Hope it helps.
>>> Best Regards,
>>>     Andriy Redko

>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean
>>>> declarations
>>>> like:
>>>>      <jaxrs:server id="restServer" basePackages="xxx">
>>>>            <jaxrs:serviceBeans>
>>>>                 <ref bean="TestApi" />
>>>>            </jaxrs:serviceBeans>
>>>>            <jaxrs:providers>
>>>>                 <…/>
>>>>            </jaxrs:providers>
>>>>            <jaxrs:features>
>>>>                 <… />
>>>>            </jaxrs:features>
>>>>            <jaxrs:inInterceptors>
>>>>                 <… />
>>>>            </jaxrs:inInterceptors>
>>>>            <jaxrs:outInterceptors>*
>>>>                 <**…**/>*
>>>>            </jaxrs:outInterceptors>*
>>>>      </jaxrs:server>




>>>> Here my “TestApi” bean interface is declared like:


>>>>       @Path("accounts")
>>>>        @Consumes(MediaType.*APPLICATION_JSON*)
>>>>        @Produces(MediaType.*APPLICATION_JSON*)
>>>>        public interface TestApi {
>>>>          …
>>>>        }


>>>> And CXF is triggered via a servlet configuration like:
>>>>      <servlet>
>>>>              <display-name>CXF Servlet</display-name>
>>>>              <servlet-name>CXFServlet</servlet-name>

>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servle
>>>> t
-class>>>>>
>>>>        </servlet>
>>>>        <servlet-mapping>
>>>>              <servlet-name>CXFServlet</servlet-name>
>>>>              <url-pattern>/services/*</url-pattern>
>>>>        </servlet-mapping>




>>>> Because I’ve got the @Path declaration on the interface type I’ve
>>>> omitted the address=”accounts” attribute on the jaxrs:server
>>>> declaration since otherwise I noticed that the server would be
>>>> listening to /basepath/services/ accounts/accounts/…).


>>>> Now this configuration works perfectly, only when shutting down the
>>>> application server cxf calls
>>>>         ServerImpl#destroy()


>>>> which delegates (via Obeservable) to
>>>> AbstractHTTPDestination#deactivate()
>>>> which calls
>>>> registry.removeDestination(path).
>>>> This path is null (no ‘address’ specified on jaxrs:server
>>>> declaration) and results in a NPE on the registry Map.
>>>> This causes an unclean shutdown of my server.


>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?
>>>> How does the ‘address’ attribute on the jaxrs:server declaration
>>>> correctly interact with the @Path parameter on the API interface?


Re: How to setup multiple JAXRS server endpoints

Posted by Andriy Redko <dr...@gmail.com>.
Hi Jean,

Indeed the way you would like to do that is somewhat tricky. 

> So I tried to keep the @Path declaration on the interface classes but changed them to @Path(“”). That does seems to work except the swagger stuff no longer correctly works. 

This is one of the possible options but OpenAPI/Swagger gets confused for a reason: the path is now implicit (not in the spec). 
So how about this option: 
 - use only one JAX-RS server (address "/")
 - host both resources but use @Path("accounts") and @Path("resources") on them respectively
 
I see that for @Path("accounts") you need to apply the "kmopApiAuthorizationFilter", that could be done using
DynamicFeature [1], [2]. If this is not the option and you would prefer to use 2 separate JAX-RS servers, you 
may need to provide your own instance of Swagger2Customizer [3], [4] which allows to transform the OpenAPI/Swagger 
on the fly. Please let me know if that would it work for you, thank you.

[1] https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/DynamicFeature.html
[2] https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born-equal.html
[3] https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger/Swagger2Customizer.html
[4] https://cxf.apache.org/docs/swagger2feature.html (has customizer property)
 

Best Regards,
    Andriy Redko

> Hi Andriy,
> I am again getting into trouble with server endpoint declarations. Now because I am adding additional JAX-RS endpoints.
> The issue is with:
> 1.      The 'address' attribute on the <jaxrs:server> declaration in combination with
> 2.      The 'url-pattern' for the CXFServlet declaration in the web.xml in combination with
> 3.      The @Path declaration in the interface class in combination with
> 4.      The @Path declaration on the interface method in combination with
> So what I had is that my web application deployed under baseUlr 'op' had one JAXRS server endpoint with declarations like:
> 1.      <jaxrs:server id="restServer" basePackages="be.dvtm.aeo.op.sodexo" address="/">
> 2.      <url-pattern>/services/*</url-pattern>
> 3.      @Path("accounts") on the public interface class
> 4.      @Path("/{authorisationId}/customerFund") on the customerFund interface method
> A valid API call would thus be e.g.: https://<hostname>:<port>/op/services/accounts/{authorizationId}/customerFund
> And this works correctly.
> We're now introducing additional JAX-RS service endpoints and now I am running into problems. This second endpoint was declared with:
> 1.      <jaxrs:server id="resourceServer" basePackages="be.dvtm.aeo.op.resources" address="/">
> 2.      <url-pattern>/services/*</url-pattern>
> 3.      @Path("resources") on the public interface class
> 4.      @Path("/NACE") on the NACE interface method
> So here a valid API call woud be: https://<hostname>:<port>/op/services/resources/NACE.
> The problem is that I can not declare two <jaxrs:server> entries with the same ‘address’ as it throws the exception:
> Caused by: org.apache.cxf.service.factory.ServiceConstructionException: There is an endpoint already running on /.
>  So I tried changing the addresses to:
> ·       address=”accounts” for the restServer
> ·       address=”resources” for the resourceServer
> But to keep the API-call URLs the same I removed the @Path declaration on the interface classes. By doing so the <jaxrs:server> bean declarations no longer loads successfully.
> So I tried to keep the @Path declaration on the interface classes but changed them to @Path(“”). That does seems to work except the swagger stuff no longer correctly works. 

> So what is the decent way to setup multiple JAX-RS server endpoints where each server has its own configuration regarding supported features:
> ·       own validation
> ·       own object and exception mappings
> ·       own swagger file generation
> ·       own logging (in separate file if possible)
> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in cooperation with swager-ui v4.5.0.
> Below the declarations of my endpoints
> <<...>>
> Thanks for any advice.
> Regards,
> J.P. Urkens 

> -----Original Message-----
> From: Andriy Redko <dr...@gmail.com>
> Sent: zaterdag 18 juni 2022 1:12
> To: Jean Pierre URKENS <je...@devoteam.com>; issues@cxf.apache.org; dev@cxf.apache.org
> Subject: Re: JAXRS server endpoint not gracefully shutdown
> Hi Jean,
>> 1. a jaxrs server  on url: '/<basePath>/services/service1'
> Correct, so in the relative form like address="/<something>", the JAX-RS endpoint path would be:
>     <baseUrl>/<servlet path mapping>/<address>/[@ApplicationPath]/[@Path]
> The @ApplicationPath is optional in this case.
>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
> The JAX-WS is very different from JAX-RS, essentially the action comes inside the SOAP message behind <baseUrl>/<servlet path mapping>/ (@Path / @ApplicationPath are not relevant there). 

>> Question: Because now address="/" is set for the jaxrs:server will
>> it also inspect requests targeted for the jaxws service as those
>> requests have start with the same path '/<basePath>/services/...
> This is a good question, I have not done it myself but I think it should work:
> the servlet dispatches according to registered services, in this regard JAX-RS and JAX-WS should not conflict. Does it work in your case? Thank you.
> Best Regards,
>     Andriy Redko
>> Hi Andriy,
>> Using address="/" seems to work but still I don't understand how
>> the following work together:
>>  - path specification in servlet mapping for the CXF servlet
>> (org.apache.cxf.transport.servlet.CXFServlet)
>>  - the 'address' attribute on the jaxrs:server bean declaration
>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the
>> service API description
>> Say I've two services with (relateive to the host) url's:
>> 1. a jaxrs server  on url: '/<basePath>/services/service1'
>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>> How do I configure above 3 aspects? Currently I have (working):
>> 1.for the jaxrs:server endpoint:
>>         - servlet path mapping: '/services/*'
>>                - jaxrs-server address attribute: address="/"
>>                - @Path annotation: @Path("service1") 2.For the
>> jaxws service endpoint:
>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS
>> requests are handleb by the same CXF servle)
>>                - jaxws:endpoint server address attribute:
>> address="/service2"
>>                - @WebService(name="service2")
>> A correct request for '1' would be '/basePath>/services/service1/<ID>'.
>> A correct request for '2' would be '/basePath>/services/service2'.
>> The jaxrs/jaxws configuration behavior seem to differ with respect to:
>>         - the server address attribute
>>         - The API annotation (@Path or @Webservice) The JAXWS
>> server address attribute doesn't seem to interfere with the
>> @Webservice annotation. While the jaxrs server address attribute
>> does seem to interfere with the @Path annotation. I would have
>> expected the jaxrs server aspects to be configured as:
>>         - servlet path mapping: '/services/*'
>>                - jaxrs-server address attribute: address="/service1"
>>                - @Path annotation: @Path("service1") but then a
>> valid request would be
>>> /services/service1/service1/<ID>'.
>> For both the 'address' attribute is relative to the servlet path.
>> The @Path Javadoc mentions that this path is relative to the
>> ApplicationPath which thus seems to be relative to the jaxrs-server
>> address attribute. As for @Webservice it doesnn't seem to be url-path related.
>> Question: Because now address="/" is set for the jaxrs:server will
>> it also inspect requests targeted for the jaxws service as those
>> requests have start with the same path '/<basePath>/services/...'.
>> Albeit somewhat confusing.
>> J.P.
>> -----Original Message-----
>> From: Andriy Redko <dr...@gmail.com>
>> Sent: dinsdag 14 juni 2022 1:08
>> To: Jean Pierre URKENS <je...@devoteam.com>;
>> issues@cxf.apache.org; dev@cxf.apache.org
>> Subject: Re: JAXRS server endpoint not gracefully shutdown
>> Hi Jean,
>> Indeed, the jaxrs:server does not expect address to be omitted, you
>> could use the "/" (and I believe an empty string would also make it):
>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...
>> </jaxrs:server> 

>> Thank you.
>> Hope it helps.
>> Best Regards,
>>     Andriy Redko 

>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean
>>> declarations
>>> like:
>>>      <jaxrs:server id="restServer" basePackages="xxx">
>>>            <jaxrs:serviceBeans>
>>>                 <ref bean="TestApi" />
>>>            </jaxrs:serviceBeans>
>>>            <jaxrs:providers>
>>>                 <…/>
>>>            </jaxrs:providers>
>>>            <jaxrs:features>
>>>                 <… />
>>>            </jaxrs:features>
>>>            <jaxrs:inInterceptors>
>>>                 <… />
>>>            </jaxrs:inInterceptors>
>>>            <jaxrs:outInterceptors>*
>>>                 <**…**/>*
>>>            </jaxrs:outInterceptors>*
>>>      </jaxrs:server> 




>>> Here my “TestApi” bean interface is declared like: 


>>>       @Path("accounts")
>>>        @Consumes(MediaType.*APPLICATION_JSON*)
>>>        @Produces(MediaType.*APPLICATION_JSON*)
>>>        public interface TestApi {
>>>          …
>>>        } 


>>> And CXF is triggered via a servlet configuration like:
>>>      <servlet>
>>>              <display-name>CXF Servlet</display-name>
>>>              <servlet-name>CXFServlet</servlet-name> 

>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servle
>>> t
-class>>>>
>>>        </servlet>
>>>        <servlet-mapping>
>>>              <servlet-name>CXFServlet</servlet-name>
>>>              <url-pattern>/services/*</url-pattern>
>>>        </servlet-mapping> 




>>> Because I’ve got the @Path declaration on the interface type I’ve
>>> omitted
>>> the address=”accounts” attribute on the jaxrs:server declaration
>>> since otherwise
>>> I noticed that the server would be listening to
>>> /basepath/services/ accounts/accounts/…). 


>>> Now this configuration works perfectly, only when shutting down
>>> the application server cxf calls
>>>         ServerImpl#destroy() 


>>> which delegates (via Obeservable) to
>>> AbstractHTTPDestination#deactivate()
>>> which calls
>>> registry.removeDestination(path).
>>> This path is null (no ‘address’ specified on jaxrs:server
>>> declaration) and results in a NPE on the registry Map.
>>> This causes an unclean shutdown of my server. 


>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?
>>> How does the ‘address’ attribute on the jaxrs:server declaration
>>> correctly interact with the @Path parameter on the API interface?


Re: JAXRS server endpoint not gracefully shutdown

Posted by Andriy Redko <dr...@gmail.com>.
Hi Jean,

JPU> 1. a jaxrs server  on url: '/<basePath>/services/service1'

Correct, so in the relative form like address="/<something>", the JAX-RS endpoint path would be:

    <baseUrl>/<servlet path mapping>/<address>/[@ApplicationPath]/[@Path]

The @ApplicationPath is optional in this case.

JPU> 2. a jaxws service endpoint on '/<basePath>/services/service2'

The JAX-WS is very different from JAX-RS, essentially the action 
comes inside the SOAP message behind <baseUrl>/<servlet path mapping>/ 
(@Path / @ApplicationPath are not relevant there).


JPU> Question: Because now address="/" is set for the jaxrs:server will it also
JPU> inspect requests targeted for the jaxws service as those requests have start
JPU> with the same path '/<basePath>/services/...

This is a good question, I have not done it myself but I think it should work: 
the servlet dispatches according to registered services, in this regard JAX-RS and
JAX-WS should not conflict. Does it work in your case? Thank you.

Best Regards,
    Andriy Redko 

JPU> Hi Andriy,

JPU> Using address="/" seems to work but still I don't understand how the
JPU> following work together:
JPU>  - path specification in servlet mapping for the CXF servlet
JPU> (org.apache.cxf.transport.servlet.CXFServlet)
JPU>  - the 'address' attribute on the jaxrs:server bean declaration
JPU>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the service
JPU> API description

JPU> Say I've two services with (relateive to the host) url's:
JPU> 1. a jaxrs server  on url: '/<basePath>/services/service1'
JPU> 2. a jaxws service endpoint on '/<basePath>/services/service2'

JPU> How do I configure above 3 aspects? Currently I have (working):
JPU> 1.for the jaxrs:server endpoint:
JPU>         - servlet path mapping: '/services/*'
JPU>                - jaxrs-server address attribute: address="/"
JPU>                - @Path annotation: @Path("service1")
JPU> 2.For the jaxws service endpoint:
JPU>         - servlet path mapping: '/services/*' (JAXWS and JAXRS requests are handleb
JPU> by the same CXF servle)
JPU>                - jaxws:endpoint server address attribute:
JPU> address="/service2"
JPU>                - @WebService(name="service2")

JPU> A correct request for '1' would be '/basePath>/services/service1/<ID>'.
JPU> A correct request for '2' would be '/basePath>/services/service2'.

JPU> The jaxrs/jaxws configuration behavior seem to differ with respect to:
JPU>         - the server address attribute
JPU>         - The API annotation (@Path or @Webservice)
JPU> The JAXWS server address attribute doesn't seem to interfere with the
JPU> @Webservice annotation. While the jaxrs server address attribute does seem
JPU> to interfere with the @Path annotation. I would have expected the jaxrs
JPU> server aspects to be configured as:
JPU>         - servlet path mapping: '/services/*'
JPU>                - jaxrs-server address attribute: address="/service1"
JPU>                - @Path annotation: @Path("service1")
JPU> but then a valid request would be
'/basePath>>/services/service1/service1/<ID>'.

JPU> For both the 'address' attribute is relative to the servlet path.
JPU> The @Path Javadoc mentions that this path is relative to the ApplicationPath
JPU> which thus seems to be relative to the jaxrs-server address attribute. As
JPU> for @Webservice it doesnn't seem to be url-path related.

JPU> Question: Because now address="/" is set for the jaxrs:server will it also
JPU> inspect requests targeted for the jaxws service as those requests have start
JPU> with the same path '/<basePath>/services/...'.

JPU> Albeit somewhat confusing.

JPU> J.P.

JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: dinsdag 14 juni 2022 1:08
JPU> To: Jean Pierre URKENS <je...@devoteam.com>;
JPU> issues@cxf.apache.org; dev@cxf.apache.org
JPU> Subject: Re: JAXRS server endpoint not gracefully shutdown

JPU> Hi Jean,

JPU> Indeed, the jaxrs:server does not expect address to be omitted, you could
JPU> use the "/" (and I believe an empty string would also make it):

JPU> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...
JPU> </jaxrs:server>


JPU> Thank you.
JPU> Hope it helps.

JPU> Best Regards,
JPU>     Andriy Redko


JPU>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean
JPU>> declarations

JPU>> like:

JPU>>      <jaxrs:server id="restServer" basePackages="xxx">

JPU>>            <jaxrs:serviceBeans>

JPU>>                 <ref bean="TestApi" />

JPU>>            </jaxrs:serviceBeans>

JPU>>            <jaxrs:providers>

JPU>>                 <…/>

JPU>>            </jaxrs:providers>

JPU>>            <jaxrs:features>

JPU>>                 <… />

JPU>>            </jaxrs:features>

JPU>>            <jaxrs:inInterceptors>

JPU>>                 <… />

JPU>>            </jaxrs:inInterceptors>

JPU>>            <jaxrs:outInterceptors>*

JPU>>                 <**…**/>*

JPU>>            </jaxrs:outInterceptors>*

JPU>>      </jaxrs:server>





JPU>> Here my “TestApi” bean interface is declared like:



JPU>>       @Path("accounts")

JPU>>        @Consumes(MediaType.*APPLICATION_JSON*)

JPU>>        @Produces(MediaType.*APPLICATION_JSON*)

JPU>>        public interface TestApi {

JPU>>          …

JPU>>        }



JPU>> And CXF is triggered via a servlet configuration like:

JPU>>      <servlet>

JPU>>              <display-name>CXF Servlet</display-name>

JPU>>              <servlet-name>CXFServlet</servlet-name>


JPU>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet
JPU>> -class>

JPU>>        </servlet>

JPU>>        <servlet-mapping>

JPU>>              <servlet-name>CXFServlet</servlet-name>

JPU>>              <url-pattern>/services/*</url-pattern>

JPU>>        </servlet-mapping>





JPU>> Because I’ve got the @Path declaration on the interface type I’ve
JPU>> omitted

JPU>> the address=”accounts” attribute on the jaxrs:server declaration
JPU>> since otherwise

JPU>> I noticed that the server would be listening to /basepath/services/
JPU>> accounts/accounts/…).



JPU>> Now this configuration works perfectly, only when shutting down the
JPU>> application server cxf calls

JPU>>         ServerImpl#destroy()



JPU>> which delegates (via Obeservable) to
JPU>> AbstractHTTPDestination#deactivate()
JPU>> which calls

JPU>> registry.removeDestination(path).

JPU>> This path is null (no ‘address’ specified on jaxrs:server
JPU>> declaration) and results in a NPE on the registry Map.

JPU>> This causes an unclean shutdown of my server.



JPU>> Is this an error in cxf or is my jaxrs:server configured incorrectly?

JPU>> How does the ‘address’ attribute on the jaxrs:server declaration
JPU>> correctly interact with the @Path parameter on the API interface?


Re: JAXRS server endpoint not gracefully shutdown

Posted by Andriy Redko <dr...@gmail.com>.
Hi Jean,

JPU> 1. a jaxrs server  on url: '/<basePath>/services/service1'

Correct, so in the relative form like address="/<something>", the JAX-RS endpoint path would be:

    <baseUrl>/<servlet path mapping>/<address>/[@ApplicationPath]/[@Path]

The @ApplicationPath is optional in this case.

JPU> 2. a jaxws service endpoint on '/<basePath>/services/service2'

The JAX-WS is very different from JAX-RS, essentially the action 
comes inside the SOAP message behind <baseUrl>/<servlet path mapping>/ 
(@Path / @ApplicationPath are not relevant there).


JPU> Question: Because now address="/" is set for the jaxrs:server will it also
JPU> inspect requests targeted for the jaxws service as those requests have start
JPU> with the same path '/<basePath>/services/...

This is a good question, I have not done it myself but I think it should work: 
the servlet dispatches according to registered services, in this regard JAX-RS and
JAX-WS should not conflict. Does it work in your case? Thank you.

Best Regards,
    Andriy Redko 

JPU> Hi Andriy,

JPU> Using address="/" seems to work but still I don't understand how the
JPU> following work together:
JPU>  - path specification in servlet mapping for the CXF servlet
JPU> (org.apache.cxf.transport.servlet.CXFServlet)
JPU>  - the 'address' attribute on the jaxrs:server bean declaration
JPU>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the service
JPU> API description

JPU> Say I've two services with (relateive to the host) url's:
JPU> 1. a jaxrs server  on url: '/<basePath>/services/service1'
JPU> 2. a jaxws service endpoint on '/<basePath>/services/service2'

JPU> How do I configure above 3 aspects? Currently I have (working):
JPU> 1.for the jaxrs:server endpoint:
JPU>         - servlet path mapping: '/services/*'
JPU>                - jaxrs-server address attribute: address="/"
JPU>                - @Path annotation: @Path("service1")
JPU> 2.For the jaxws service endpoint:
JPU>         - servlet path mapping: '/services/*' (JAXWS and JAXRS requests are handleb
JPU> by the same CXF servle)
JPU>                - jaxws:endpoint server address attribute:
JPU> address="/service2"
JPU>                - @WebService(name="service2")

JPU> A correct request for '1' would be '/basePath>/services/service1/<ID>'.
JPU> A correct request for '2' would be '/basePath>/services/service2'.

JPU> The jaxrs/jaxws configuration behavior seem to differ with respect to:
JPU>         - the server address attribute
JPU>         - The API annotation (@Path or @Webservice)
JPU> The JAXWS server address attribute doesn't seem to interfere with the
JPU> @Webservice annotation. While the jaxrs server address attribute does seem
JPU> to interfere with the @Path annotation. I would have expected the jaxrs
JPU> server aspects to be configured as:
JPU>         - servlet path mapping: '/services/*'
JPU>                - jaxrs-server address attribute: address="/service1"
JPU>                - @Path annotation: @Path("service1")
JPU> but then a valid request would be
'/basePath>>/services/service1/service1/<ID>'.

JPU> For both the 'address' attribute is relative to the servlet path.
JPU> The @Path Javadoc mentions that this path is relative to the ApplicationPath
JPU> which thus seems to be relative to the jaxrs-server address attribute. As
JPU> for @Webservice it doesnn't seem to be url-path related.

JPU> Question: Because now address="/" is set for the jaxrs:server will it also
JPU> inspect requests targeted for the jaxws service as those requests have start
JPU> with the same path '/<basePath>/services/...'.

JPU> Albeit somewhat confusing.

JPU> J.P.

JPU> -----Original Message-----
JPU> From: Andriy Redko <dr...@gmail.com>
JPU> Sent: dinsdag 14 juni 2022 1:08
JPU> To: Jean Pierre URKENS <je...@devoteam.com>;
JPU> issues@cxf.apache.org; dev@cxf.apache.org
JPU> Subject: Re: JAXRS server endpoint not gracefully shutdown

JPU> Hi Jean,

JPU> Indeed, the jaxrs:server does not expect address to be omitted, you could
JPU> use the "/" (and I believe an empty string would also make it):

JPU> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...
JPU> </jaxrs:server>


JPU> Thank you.
JPU> Hope it helps.

JPU> Best Regards,
JPU>     Andriy Redko


JPU>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean
JPU>> declarations

JPU>> like:

JPU>>      <jaxrs:server id="restServer" basePackages="xxx">

JPU>>            <jaxrs:serviceBeans>

JPU>>                 <ref bean="TestApi" />

JPU>>            </jaxrs:serviceBeans>

JPU>>            <jaxrs:providers>

JPU>>                 <…/>

JPU>>            </jaxrs:providers>

JPU>>            <jaxrs:features>

JPU>>                 <… />

JPU>>            </jaxrs:features>

JPU>>            <jaxrs:inInterceptors>

JPU>>                 <… />

JPU>>            </jaxrs:inInterceptors>

JPU>>            <jaxrs:outInterceptors>*

JPU>>                 <**…**/>*

JPU>>            </jaxrs:outInterceptors>*

JPU>>      </jaxrs:server>





JPU>> Here my “TestApi” bean interface is declared like:



JPU>>       @Path("accounts")

JPU>>        @Consumes(MediaType.*APPLICATION_JSON*)

JPU>>        @Produces(MediaType.*APPLICATION_JSON*)

JPU>>        public interface TestApi {

JPU>>          …

JPU>>        }



JPU>> And CXF is triggered via a servlet configuration like:

JPU>>      <servlet>

JPU>>              <display-name>CXF Servlet</display-name>

JPU>>              <servlet-name>CXFServlet</servlet-name>


JPU>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet
JPU>> -class>

JPU>>        </servlet>

JPU>>        <servlet-mapping>

JPU>>              <servlet-name>CXFServlet</servlet-name>

JPU>>              <url-pattern>/services/*</url-pattern>

JPU>>        </servlet-mapping>





JPU>> Because I’ve got the @Path declaration on the interface type I’ve
JPU>> omitted

JPU>> the address=”accounts” attribute on the jaxrs:server declaration
JPU>> since otherwise

JPU>> I noticed that the server would be listening to /basepath/services/
JPU>> accounts/accounts/…).



JPU>> Now this configuration works perfectly, only when shutting down the
JPU>> application server cxf calls

JPU>>         ServerImpl#destroy()



JPU>> which delegates (via Obeservable) to
JPU>> AbstractHTTPDestination#deactivate()
JPU>> which calls

JPU>> registry.removeDestination(path).

JPU>> This path is null (no ‘address’ specified on jaxrs:server
JPU>> declaration) and results in a NPE on the registry Map.

JPU>> This causes an unclean shutdown of my server.



JPU>> Is this an error in cxf or is my jaxrs:server configured incorrectly?

JPU>> How does the ‘address’ attribute on the jaxrs:server declaration
JPU>> correctly interact with the @Path parameter on the API interface?


RE: JAXRS server endpoint not gracefully shutdown

Posted by Jean Pierre URKENS <je...@devoteam.com.INVALID>.
Hi Andriy,

Using address="/" seems to work but still I don't understand how the
following work together:
 - path specification in servlet mapping for the CXF servlet
(org.apache.cxf.transport.servlet.CXFServlet)
 - the 'address' attribute on the jaxrs:server bean declaration
 - the javax.ws.rs.Path or javax.jws.WebService annotation on the service
API description

Say I've two services with (relateive to the host) url's:
1. a jaxrs server  on url: '/<basePath>/services/service1'
2. a jaxws service endpoint on '/<basePath>/services/service2'

How do I configure above 3 aspects? Currently I have (working):
1.for the jaxrs:server endpoint:
	- servlet path mapping: '/services/*'
               - jaxrs-server address attribute: address="/"
               - @Path annotation: @Path("service1")
2.For the jaxws service endpoint:
	- servlet path mapping: '/services/*' (JAXWS and JAXRS requests are handleb
by the same CXF servle)
               - jaxws:endpoint server address attribute:
address="/service2"
               - @WebService(name="service2")

A correct request for '1' would be '/basePath>/services/service1/<ID>'.
A correct request for '2' would be '/basePath>/services/service2'.

The jaxrs/jaxws configuration behavior seem to differ with respect to:
	- the server address attribute
	- The API annotation (@Path or @Webservice)
The JAXWS server address attribute doesn't seem to interfere with the
@Webservice annotation. While the jaxrs server address attribute does seem
to interfere with the @Path annotation. I would have expected the jaxrs
server aspects to be configured as:
	- servlet path mapping: '/services/*'
               - jaxrs-server address attribute: address="/service1"
               - @Path annotation: @Path("service1")
but then a valid request would be
'/basePath>/services/service1/service1/<ID>'.

For both the 'address' attribute is relative to the servlet path.
The @Path Javadoc mentions that this path is relative to the ApplicationPath
which thus seems to be relative to the jaxrs-server address attribute. As
for @Webservice it doesnn't seem to be url-path related.

Question: Because now address="/" is set for the jaxrs:server will it also
inspect requests targeted for the jaxws service as those requests have start
with the same path '/<basePath>/services/...'.

Albeit somewhat confusing.

J.P.

-----Original Message-----
From: Andriy Redko <dr...@gmail.com>
Sent: dinsdag 14 juni 2022 1:08
To: Jean Pierre URKENS <je...@devoteam.com>;
issues@cxf.apache.org; dev@cxf.apache.org
Subject: Re: JAXRS server endpoint not gracefully shutdown

Hi Jean,

Indeed, the jaxrs:server does not expect address to be omitted, you could
use the "/" (and I believe an empty string would also make it):

<jaxrs:server id="restServer" basePackages="xxx" address="/"> ...
</jaxrs:server>


Thank you.
Hope it helps.

Best Regards,
    Andriy Redko


JPU> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean
JPU> declarations

JPU> like:

JPU>      <jaxrs:server id="restServer" basePackages="xxx">

JPU>            <jaxrs:serviceBeans>

JPU>                 <ref bean="TestApi" />

JPU>            </jaxrs:serviceBeans>

JPU>            <jaxrs:providers>

JPU>                 <…/>

JPU>            </jaxrs:providers>

JPU>            <jaxrs:features>

JPU>                 <… />

JPU>            </jaxrs:features>

JPU>            <jaxrs:inInterceptors>

JPU>                 <… />

JPU>            </jaxrs:inInterceptors>

JPU>            <jaxrs:outInterceptors>*

JPU>                 <**…**/>*

JPU>            </jaxrs:outInterceptors>*

JPU>      </jaxrs:server>





JPU> Here my “TestApi” bean interface is declared like:



JPU>       @Path("accounts")

JPU>        @Consumes(MediaType.*APPLICATION_JSON*)

JPU>        @Produces(MediaType.*APPLICATION_JSON*)

JPU>        public interface TestApi {

JPU>          …

JPU>        }



JPU> And CXF is triggered via a servlet configuration like:

JPU>      <servlet>

JPU>              <display-name>CXF Servlet</display-name>

JPU>              <servlet-name>CXFServlet</servlet-name>


JPU> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet
JPU> -class>

JPU>        </servlet>

JPU>        <servlet-mapping>

JPU>              <servlet-name>CXFServlet</servlet-name>

JPU>              <url-pattern>/services/*</url-pattern>

JPU>        </servlet-mapping>





JPU> Because I’ve got the @Path declaration on the interface type I’ve
JPU> omitted

JPU> the address=”accounts” attribute on the jaxrs:server declaration
JPU> since otherwise

JPU> I noticed that the server would be listening to /basepath/services/
JPU> accounts/accounts/…).



JPU> Now this configuration works perfectly, only when shutting down the
JPU> application server cxf calls

JPU>         ServerImpl#destroy()



JPU> which delegates (via Obeservable) to
JPU> AbstractHTTPDestination#deactivate()
JPU> which calls

JPU> registry.removeDestination(path).

JPU> This path is null (no ‘address’ specified on jaxrs:server
JPU> declaration) and results in a NPE on the registry Map.

JPU> This causes an unclean shutdown of my server.



JPU> Is this an error in cxf or is my jaxrs:server configured incorrectly?

JPU> How does the ‘address’ attribute on the jaxrs:server declaration
JPU> correctly interact with the @Path parameter on the API interface?