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 <[email protected]>
JPU> Sent: dinsdag 9 mei 2023 9:25
JPU> To: 'Andriy Redko' <[email protected]>
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 <[email protected]>
JPU> Sent: maandag 8 mei 2023 23:15
JPU> To: Jean Pierre URKENS <[email protected]>; CXF Dev List
JPU> <[email protected]>
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 <[email protected]>
>> Sent: zaterdag 18 juni 2022 1:12
>> To: Jean Pierre URKENS <[email protected]>;
>> [email protected]; [email protected]
>> 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 <[email protected]>
>>> Sent: dinsdag 14 juni 2022 1:08
>>> To: Jean Pierre URKENS <[email protected]>;
>>> [email protected]; [email protected]
>>> 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?