private void addRouteDefinition()

in core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java [1096:1315]


    private void addRouteDefinition(
            CamelContext camelContext, List<VerbDefinition> verbs, List<RouteDefinition> answer,
            String component, String producerComponent) {
        for (VerbDefinition verb : verbs) {
            // use a route as facade for this REST service
            RouteDefinition route = new RouteDefinition();
            if (verb.getTo() == null) {
                throw new IllegalArgumentException("Rest service: " + verb + " must have to endpoint configured.");
            }
            if (verb.getRouteId() != null) {
                route.routeId(parseText(camelContext, verb.getRouteId()));
            }
            if (verb.getStreamCache() != null) {
                route.streamCache(parseText(camelContext, verb.getStreamCache()));
            }
            route.getOutputs().add(verb.getTo());

            // add the binding
            RestBindingDefinition binding = new RestBindingDefinition();
            binding.setComponent(component);
            binding.setType(parseText(camelContext, verb.getType()));
            binding.setTypeClass(verb.getTypeClass());
            binding.setOutType(parseText(camelContext, verb.getOutType()));
            binding.setOutTypeClass(verb.getOutTypeClass());
            // verb takes precedence over configuration on rest
            if (verb.getBindingMode() != null) {
                binding.setBindingMode(parseText(camelContext, verb.getBindingMode()));
            } else {
                binding.setBindingMode(getBindingMode());
            }
            if (verb.getConsumes() != null) {
                binding.setConsumes(parseText(camelContext, verb.getConsumes()));
            } else {
                binding.setConsumes(getConsumes());
            }
            if (verb.getProduces() != null) {
                binding.setProduces(parseText(camelContext, verb.getProduces()));
            } else {
                binding.setProduces(getProduces());
            }
            if (binding.getType() != null || binding.getOutType() != null && binding.getBindingMode() != null) {
                // okay we have binding mode and in/out type defined - then we can infer consume/produces
                String mode = binding.getBindingMode();
                if ("json".equals(mode)) {
                    if (binding.getConsumes() == null && binding.getType() != null) {
                        binding.setConsumes("application/json");
                    }
                    if (binding.getProduces() == null && binding.getOutType() != null) {
                        binding.setProduces("application/json");
                    }
                } else if ("xml".equals(mode)) {
                    if (binding.getConsumes() == null && binding.getType() != null) {
                        binding.setConsumes("application/xml");
                    }
                    if (binding.getProduces() == null && binding.getOutType() != null) {
                        binding.setProduces("application/xml");
                    }
                } else if ("json_xml".equals(mode)) {
                    if (binding.getConsumes() == null && binding.getType() != null) {
                        binding.setConsumes("application/json;application/xml");
                    }
                    if (binding.getProduces() == null && binding.getOutType() != null) {
                        binding.setProduces("application/json;application/xml");
                    }
                }
            }
            if (verb.getSkipBindingOnErrorCode() != null) {
                binding.setSkipBindingOnErrorCode(parseText(camelContext, verb.getSkipBindingOnErrorCode()));
            } else {
                binding.setSkipBindingOnErrorCode(getSkipBindingOnErrorCode());
            }
            if (verb.getClientRequestValidation() != null) {
                binding.setClientRequestValidation(parseText(camelContext, verb.getClientRequestValidation()));
            } else {
                binding.setClientRequestValidation(getClientRequestValidation());
            }
            if (verb.getEnableCORS() != null) {
                binding.setEnableCORS(parseText(camelContext, verb.getEnableCORS()));
            } else {
                binding.setEnableCORS(getEnableCORS());
            }
            if (verb.getEnableNoContentResponse() != null) {
                binding.setEnableNoContentResponse(parseText(camelContext, verb.getEnableNoContentResponse()));
            } else {
                binding.setEnableNoContentResponse(getEnableNoContentResponse());
            }
            for (ParamDefinition param : verb.getParams()) {
                // register all the default values for the query and header parameters
                RestParamType type = param.getType();
                if ((RestParamType.query == type || RestParamType.header == type)
                        && ObjectHelper.isNotEmpty(param.getDefaultValue())) {
                    binding.addDefaultValue(param.getName(), parseText(camelContext, param.getDefaultValue()));
                }
                // register all allowed values for the query and header parameters
                if ((RestParamType.query == type || RestParamType.header == type)
                        && param.getAllowableValues() != null) {
                    binding.addAllowedValue(param.getName(), parseText(camelContext, param.getAllowableValuesAsCommaString()));
                }
                // register which parameters are required
                Boolean required = param.getRequired();
                if (required != null && required) {
                    if (RestParamType.query == type) {
                        binding.addRequiredQueryParameter(param.getName());
                    } else if (RestParamType.header == type) {
                        binding.addRequiredHeader(param.getName());
                    } else if (RestParamType.body == type) {
                        binding.setRequiredBody(true);
                    }
                }
            }

            route.setRestBindingDefinition(binding);

            // append options
            Map<String, Object> options = new HashMap<>();
            if (binding.getConsumes() != null) {
                options.put("consumes", binding.getConsumes());
            }
            if (binding.getProduces() != null) {
                options.put("produces", binding.getProduces());
            }
            // append optional type binding information
            String inType = binding.getType();
            if (inType != null) {
                options.put("inType", inType);
            }
            String outType = binding.getOutType();
            if (outType != null) {
                options.put("outType", outType);
            }
            if (component != null && !component.isEmpty()) {
                options.put("consumerComponentName", component);
            }
            if (producerComponent != null && !producerComponent.isEmpty()) {
                options.put("producerComponentName", producerComponent);
            }

            // include optional description, which we favor from 1) to/route
            // description 2) verb description 3) rest description
            // this allows end users to define general descriptions and override
            // then per to/route or verb
            final String description = getDescription(verb, route);
            if (description != null) {
                options.put("description", parseText(camelContext, description));
            }

            String path = parseText(camelContext, getPath());
            String s1 = FileUtil.stripTrailingSeparator(path);
            String s2 = FileUtil.stripLeadingSeparator(parseText(camelContext, verb.getPath()));
            String allPath;
            if (s1 != null && s2 != null) {
                allPath = s1 + "/" + s2;
            } else if (path != null) {
                allPath = path;
            } else {
                allPath = parseText(camelContext, verb.getPath());
            }

            // each {} is a parameter (url templating)
            Set<String> toRemove = null;
            if (allPath != null && allPath.contains("?")) {
                // special when having query parameters
                String path1 = StringHelper.before(allPath, "?");
                uriTemplating(camelContext, verb, path1, false);
                String path2 = StringHelper.after(allPath, "?");
                // there may be some query parameters that are templates which we then must remove
                toRemove = uriTemplating(camelContext, verb, path2, true);
            } else {
                // no query parameters
                uriTemplating(camelContext, verb, allPath, false);
            }

            if (verb.getType() != null) {
                String bodyType = parseText(camelContext, verb.getType());
                ParamDefinition param = findParam(verb, RestParamType.body.name());
                if (param == null) {
                    // must be body type and set the model class as data type
                    param(verb).name(RestParamType.body.name()).type(RestParamType.body).dataType(bodyType).endParam();
                } else {
                    // must be body type and set the model class as data type
                    param.type(RestParamType.body).dataType(bodyType);
                }
            }

            // create the from endpoint uri which is using the rest component
            String from = buildFromUri(camelContext, verb);

            // rebuild uri without these query parameters
            if (toRemove != null && !toRemove.isEmpty()) {
                try {
                    Map<String, Object> query = URISupport.parseQuery(URISupport.extractQuery(from));
                    // remove if the value matches, eg: auth={myAuth}
                    toRemove.forEach(v -> {
                        query.values().removeIf(qv -> qv.toString().equals(v));
                    });
                    from = URISupport.stripQuery(from);
                    if (!query.isEmpty()) {
                        String q = URISupport.createQueryString(query);
                        from = URISupport.stripQuery(from) + "?" + q;
                    }
                } catch (Exception e) {
                    throw RuntimeCamelException.wrapRuntimeCamelException(e);
                }
            }

            // append additional options
            if (!options.isEmpty()) {
                try {
                    from = URISupport.appendParametersToURI(from, options);
                } catch (Exception e) {
                    throw RuntimeCamelException.wrapRuntimeCamelException(e);
                }
            }

            // the route should be from this rest endpoint
            route.fromRest(from);
            route.setRestDefinition(this);
            answer.add(route);
        }
    }