Yes, SwaggerUI works too!
I noticed that v2.x of swagger-jaxrs relates to OpenApi v3.1.x while my spec
is compliant with OpenApi v3.0.x, so I am going to stick with v2.1.13 which
seems to be that last version for OpenApi v3.0.x.

I thought the @Parameter only applied to input parameters ("query",
"header", "path" or "cookie" parameters), but I'll give it a try.

J.P.

-----Original Message-----
From: Andriy Redko <drr...@gmail.com>
Sent: woensdag 12 juli 2023 22:16
To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>; dev@cxf.apache.org
Subject: Re: How to setup multiple JAXRS server endpoints

Hi Jean,

That's awesome, have you got SwaggerUI working as well?

Yes, you could use 2.2.15 (we already updated to this version, no
regressions). It seems like the description applies to the whole schema
(which is the same for both properties), may be you could use @Parameter
instead:

@Parameter(description="The description I want for prop1")

Thank you.

Best Regards,
    Andriy Redko

> Hi Andriy,
> After having migrated everything to "io.swagger.v3.oas.annotations.*" the
> swagger endpoints for each of my services became active.
> So far so good, but I do notice that there are discrepancies when
> annotating models, e.g.:
>  public class Model1 {
>   @Schema(description="The description I want for prop1")
>    private Model2 prop1;
>   @Schema(description="The description I want for prop2")
>    private Model2 prop2;
>   ...
> }
> When I generate the openapi.[json|yaml] specification I see that both
> prop1 and prop2 have a reference to the schema component "Model2" with
> description ' The description I want for prop2' which is inappropriate for
> 'prop1'.
> It is not unlikely to have multiple properties within one Model that are
> of the same class but are semantically used in a different context. E.g.
> something as simple as a ShipmentOrder having two 'Address' properties
> 'from' and 'to' would result in wrong API documentation.
> I am aware it has nothing to do with CXF but rather with
> swagger-jaxrs2-vx.y.z.jar and depending libraries. CXF-3.5.6 has
> dependency on swagger-jaxrs2-2.1.13.jar. Would it be an issue to replace
> this dependency with e.g. swagger-jaxrs2-2.2.15.jar (latest stable release
> according to maven central repo)?
> J.P.
> -----Original Message-----
> From: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>
> Sent: woensdag 12 juli 2023 8:25
> To: 'Andriy Redko' <drr...@gmail.com>; 'dev@cxf.apache.org'
> <dev@cxf.apache.org>
> Subject: RE: How to setup multiple JAXRS server endpoints I seem to be
> mistaken here, the endpoint was loaded (I did a manual HTTP GET test to
> the endpoint to verify this) although no breakpoints where hit during
> startup.
> I am first going to complete the migration to
> "io.swagger.v3.oas.annotations.*" annotations for all endpoints and then I
> am going to test again.
> The application is composed of libraries, some of which use SLF4J but most
> use LOG4J for logging.
> J.P.

> -----Original Message-----
> From: Andriy Redko <drr...@gmail.com>
> Sent: woensdag 12 juli 2023 1:13
> To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>;
> dev@cxf.apache.org
> Subject: Re: How to setup multiple JAXRS server endpoints Hi Jean, The
> OpenApiFeature$Portable#initiliaze(…) should definitely be called
> (otherwise you shouldn't even see the openapi.json endpoint), so I am not
> sure why these are not triggering for you.
>
> For logging, it seems like you are using SLF4J
> (org.apache.cxf.common.logging.Slf4jLogger),
> and also reload4j (aka log4j), why do you need both?
> Thank you.
> Best Regards,
>     Andriy Redko
JPU>> After some code investigation:


JPU>> OpenApiFeature implements SwaggerUiSupport and in its
JPU>> portable#registerSwaggerUiResources(…) method it will call
JPU>> SwaggerUiSupport#getSwaggerUi(…) which will register the
SwaggerUiService.


JPU>> I have put breakpoints on:
JPU>>    - OpenApiFeature$Portable#initiliaze(…)
JPU>>    - SwaggerUiService constructor
JPU>>    - SwaggerUiSupport#getSwaggerUi(…)


JPU>> but none of them are hit when starting my application?


JPU>> Although the (spring) logging shows all beans in my
JPU>> cxf-endpoints.xml have been created?
JPU>> The *WADL* and *OpenAPI* endpoints to get the specification work.
JPU>> Even the actual endpoint seems to work although I didn’t hit any of
JPU>> the breakpoint?


JPU>> CXF, also doesn’t seem to log a lot, I am hardly getting any log
JPU>> entries although log level I set to DEBUG.
JPU>> My logging (except wire message logging) for cxf is setup correctly
JPU>> (I
JPU>> think):
JPU>>    - ../META-INF/cxf/org.apache.cxf.Logger contains the line
JPU>>    ‘org.apache.cxf.common.logging.Slf4jLogger’
JPU>>    - slf4j-api-1.7.36.jar, slf4j-reload4j-1.7.36.jar and
JPU>>    reload4j-1.2.19.jar are on the classpath
JPU>>    - the log4j.properties file contains the line:
JPU>>    ‘log4j.logger.org.apache.cxf=DEBUG’


JPU>> There are no special instructions mentioned on
JPU>> https://cxf.apache.org/docs/general-cxf-logging.html so the above
JPU>> should work (it works for all other packages I use in my application).


JPU>> J.P.
JPU>> *From:* Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>
JPU>> *Sent:* dinsdag 11 juli 2023 9:58
JPU>> *To:* 'Andriy Redko' <drr...@gmail.com>; 'dev@cxf.apache.org' <
dev@cxf.apache.org>>>
JPU>> *Subject:* RE: How to setup multiple JAXRS server endpoints


JPU>> Hi Andriy,


JPU>> As a test I removed all JAX-RS endpoints that use Swagger v2
JPU>> annotations 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)
JPU>> *WADL* and *OpenAPI* endpoints, no Swagger UI endpoint:




JPU>> So there is some configuration missing to detect/activate the
JPU>> Swagger endpoint. When I look at the samples that come with the
JPU>> distribution of CXF (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 <drr...@gmail.com>
JPU>> Sent: dinsdag 11 juli 2023 3:44
JPU>> To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>;
JPU>> dev@cxf.apache.org
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
JPU>> be honest we have never tested or envisioned the application that
JPU>> would use OpenAPI 2.0 (Swagger) and OpenAPI 3.0 at the same time, I
JPU>> am afraid this is just not supported. You may get things back on
JPU>> track when going with 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 <jean-pierre.urk...@devoteam.com>
>>> *Sent:* maandag 10 juli 2023 13:43
>>> *To:* 'Andriy Redko' <drr...@gmail.com>
>>> *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/o
>>> i
>>> 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 <drr...@gmail.com>
>>> Sent: donderdag 25 mei 2023 2:27
>>> To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>;
>>> dev@cxf.apache.org
>>> 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 = "


>>>>       *jean-pierre.urk...@devoteam.com* <
>>> jean-pierre.urk...@devoteam.com>


>>>>       ")),






>>>>               securityDefinition =


>>>>       @SecurityDefinition(apiKeyAuthDefinitions=


>>> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="A
>>> u
>>> thorization",description="Use*


>>>>       <{@ApiKeyAuthDefinition(key=> the format 'Bearer


>>>>       &lt;accessToken&gt;'")})






>>>>       )






>>>>       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 <jean-pierre.urk...@devoteam.com>


>>>> Sent: dinsdag 23 mei 2023 12:52


>>>> To: 'Andriy Redko' <drr...@gmail.com>; 'dev@cxf.apache.org' <




>>>> 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 <drr...@gmail.com>






>>>> Sent: dinsdag 23 mei 2023 3:42






>>>> To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>;


>>>> dev@cxf.apache.org






>>>> 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 <drr...@gmail.com>






>>>>> Sent: maandag 8 mei 2023 23:15






>>>>> To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>; 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}/c
>>>>>> u
>>>>>> 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 <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</serv
>>>>>>>> l
>>>>>>>> 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?






>>>>> <<...>>

Reply via email to