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 <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