Got it, thank you (the Swagger sometimes does surprising things).

Thursday, July 13, 2023, 1:33:07 AM, you wrote:

JPU> The @Parameter annotation seems to be ignored at this level.

JPU> -----Original Message-----
JPU> From: Jean Pierre URKENS <[email protected]>
JPU> Sent: donderdag 13 juli 2023 7:11
JPU> To: 'Andriy Redko' <[email protected]>; '[email protected]'
JPU> <[email protected]>
JPU> Subject: RE: How to setup multiple JAXRS server endpoints

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

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

JPU> J.P.

JPU> -----Original Message-----
JPU> From: Andriy Redko <[email protected]>
JPU> Sent: woensdag 12 juli 2023 22:16
JPU> To: Jean Pierre URKENS <[email protected]>; 
[email protected]
JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

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

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

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

JPU> Thank you.

JPU> Best Regards,
JPU>     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 <[email protected]>
>> Sent: woensdag 12 juli 2023 8:25
>> To: 'Andriy Redko' <[email protected]>; '[email protected]'
>> <[email protected]>
>> 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 <[email protected]>
>> Sent: woensdag 12 juli 2023 1:13
>> To: Jean Pierre URKENS <[email protected]>;
>> [email protected]
>> 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
JPU> 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
JPU>>> of 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
JPU>>> correctly (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 <[email protected]>
JPU>>> *Sent:* dinsdag 11 juli 2023 9:58
JPU>>> *To:* 'Andriy Redko' <[email protected]>; '[email protected]' <
[email protected]>>>>
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
JPU> configured to activate this?
JPU>>> Do you have any idea how the SwaggerUiService is picked up when
JPU> 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]>;
JPU>>> [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
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 <[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/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 <[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="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 <[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}/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 <[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</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