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?