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 <drr...@gmail.com>
JPU> Sent: vrijdag 19 mei 2023 3:04
JPU> To: Jean Pierre URKENS <jean-pierre.urk...@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 <jean-pierre.urk...@devoteam.com>
JPU>> Sent: dinsdag 9 mei 2023 9:25
JPU>> To: 'Andriy Redko' <drr...@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 <drr...@gmail.com>
JPU>> Sent: maandag 8 mei 2023 23:15
JPU>> To: Jean Pierre URKENS <jean-pierre.urk...@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
>>> 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 <drr...@gmail.com>
>>> Sent: zaterdag 18 juni 2022 1:12
>>> To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>;
>>> iss...@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 <drr...@gmail.com>
>>>> Sent: dinsdag 14 juni 2022 1:08
>>>> To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>;
>>>> iss...@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?

Reply via email to