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 <[email protected]>
JPU> Sent: dinsdag 11 juli 2023 3:44
JPU> To: Jean Pierre URKENS <[email protected]>;
[email protected]
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 <[email protected]>
>> *Sent:* maandag 10 juli 2023 13:43
>> *To:* 'Andriy Redko' <[email protected]>
>> *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 <[email protected]>
>> Sent: donderdag 25 mei 2023 2:27
>> To: Jean Pierre URKENS <[email protected]>;
>> [email protected]
>> 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 = "
>>> *[email protected]* <
>> [email protected]>
>>> ")),
>>> securityDefinition =
>>> @SecurityDefinition(apiKeyAuthDefinitions=
>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="Au
>> thorization",description="Use*
>>> <{@ApiKeyAuthDefinition(key=> the format 'Bearer
>>> <accessToken>'")})
>>> )
>>> 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 <[email protected]>
>>> Sent: dinsdag 23 mei 2023 12:52
>>> To: 'Andriy Redko' <[email protected]>; '[email protected]' <
>>> 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 <[email protected]>
>>> Sent: dinsdag 23 mei 2023 3:42
>>> To: Jean Pierre URKENS <[email protected]>;
>>> [email protected]
>>> 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 <[email protected]>
>>>> Sent: maandag 8 mei 2023 23:15
>>>> To: Jean Pierre URKENS <[email protected]>; 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 <[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</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?
>>>> <<...>>