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 >>>>> <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}/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? >>>>>> <<...>>
