Hi,

I have encountered an issue relating to the Swagger component of Camel, I
believe it is related to the RestModelConvertor that is used when creating
the Swagger model from the Rest API model from Camel.

When a model that is directly referenced (e.g. an out-type) is added to the
Swagger.definitions map by that method, it is decorated with the extension
of "x-className". Any models that are subsequently referenced from the
original model are also added to the definitions map, undecorated.

Definitions needs to be decorated as such in order to be returned later as
ReferenceProperties in RestSwaggerReader.modelTypeAsRef(), otherwise they
are returned as StringProperties.

The issue seems to that there is nothing preventing a decorated element in
the Swagger.definitions map from being overwritten by an undecorated version
of the same class, if the REST API Verbs in Camel is ordered in a certain
way.

E.g.

API 1 returns Model A, which references Model B.
API 2 returns Model B.

Case 1 (no issue):

API 1 is loaded first.
Model A is added to Swagger.definition map decorated with "x-className",
Model B is added to the definition map undecorated.
API 2 is then loaded.
Model B is then decorated with "x-classname" and replaces the previous Model
B element in the definition map.

All good

Case 2 (the issue):

Consider that API 2 is loaded before API one, then after both API's are
loaded the definitions map contains a Decorated Model A but an undecorated
Model B.

Then when the RestSwaggerReader tries to set the schema on the response
element of API2 (towards the end of doParseVerbs()), it fails to find Model
B as a reference Property and adds it as a StringProperty, so the Model does
not show in Swagger UI and broke our validation tests.

We have many existing APIs and Models, all working perfectly, and I came
across this specific scenario today. I would appreciate If someone was able
to verify if this indeed is a defect or I am mistaken in my understanding.

If this is a bug, would a suitable fix to be to check the definition map for
an existing Model and NOT replace it, if it is decorated with the
"x-className" extension? Happy to get involved with a Pull request if
required.

Thanks
Tom

For ease: below is the code in question

---------------------------------------------
RestSwaggerReader.class

  private void appendModels(Class clazz, Swagger swagger) {
        RestModelConverters converters = new RestModelConverters();
        final Map<String, Model> models = converters.readClass(clazz);
        for (Map.Entry<String, Model> entry : models.entrySet()) {
            swagger.model(entry.getKey(), entry.getValue());
        }
    }


-----------------------------------------------------------
RestModelConverters.class

    public Map<String, Model> readClass(Class clazz) {
        String name = clazz.getName();
        Map<String, Model> resolved = super.read(clazz);
        if (resolved != null) {
            for (Model model : resolved.values()) {
                // enrich with the class name of the model
                model.getVendorExtensions().put("x-className", new
StringProperty(name));
            }

            // read any extra using read-all
            Map<String, Model> extra = super.readAll(clazz);
            if (extra != null) {
                for (Map.Entry<String, Model> entry : extra.entrySet()) {
                    if (!resolved.containsKey(entry.getKey())) {
                        resolved.put(entry.getKey(), entry.getValue());
                    }
                }
            }
        }
        return resolved;
    }







--
View this message in context: 
http://camel.465427.n5.nabble.com/Bug-in-RestSwaggerReader-appendModels-need-confirmation-tp5778821.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Reply via email to