This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new 8e6c039a352 Inline rest-dsl (#13338) 8e6c039a352 is described below commit 8e6c039a352a156d8d661719c7d453b8c3765526 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Wed Feb 28 13:49:53 2024 +0100 Inline rest-dsl (#13338) CAMEL-20466: camel-core - Rest DSL to be inlined by default to avoid clutter up list of routes --- .../main/camel-main-configuration-metadata.json | 2 +- .../camel/catalog/models/restConfiguration.json | 2 +- .../apache/camel/catalog/schemas/camel-spring.xsd | 9 ++++--- .../apache/camel/component/rest/RestRefTest.java | 3 ++- .../undertow/rest/RestManagementTest.java | 2 +- .../org/apache/camel/spi/RestConfiguration.java | 11 ++++---- .../camel/impl/engine/AbstractCamelContext.java | 10 +++----- .../camel/impl/console/SourceDevConsole.java | 2 ++ .../java/org/apache/camel/impl/DefaultModel.java | 29 ++++++++++++++++++++++ .../apache/camel/model/rest/restConfiguration.json | 2 +- .../org/apache/camel/model/RouteDefinition.java | 2 +- .../model/rest/RestConfigurationDefinition.java | 29 ++++++++++++---------- .../component/rest/FromRestGetPolicyTest.java | 3 ++- .../camel/component/rest/FromRestGetTest.java | 3 ++- .../camel-main-configuration-metadata.json | 2 +- core/camel-main/src/main/docs/main.adoc | 2 +- .../camel/management/ManagedFromRestGetTest.java | 10 +++++--- .../management/ManagedFromRestPlaceholderTest.java | 4 +-- .../ROOT/pages/camel-4x-upgrade-guide-4_5.adoc | 9 +++++++ .../dsl/js/JavaScriptRoutesBuilderLoaderTest.java | 3 ++- .../dsl/yaml/common/YamlDeserializerBase.java | 9 +++++-- .../dsl/yaml/deserializers/ModelDeserializers.java | 2 +- .../generated/resources/schema/camelYamlDsl.json | 2 +- 23 files changed, 102 insertions(+), 50 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json index f1e51f670bf..f2f63e72a4a 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json @@ -228,7 +228,7 @@ { "name": "camel.rest.endpointProperties", "description": "Sets additional options on endpoint level", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "object", "javaType": "java.util.Map" }, { "name": "camel.rest.host", "description": "Sets the hostname to use by the REST consumer", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "string", "javaType": "java.lang.String" }, { "name": "camel.rest.hostNameResolver", "description": "Sets the resolver to use for resolving hostname", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "object", "javaType": "org.apache.camel.spi.RestHostNameResolver", "defaultValue": "RestHostNameResolver.allLocalIp", "enum": [ "allLocalIp", "localIp", "localHostName" ] }, - { "name": "camel.rest.inlineRoutes", "description": "Inline routes in rest-dsl which are linked using direct endpoints. By default, each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from rest-dsl). Enabling this allows Camel to optimize and inline this as a single route, however this requires to use direct endpoints, which must be unique per service. This option is default false.", "sourceType" [...] + { "name": "camel.rest.inlineRoutes", "description": "Inline routes in rest-dsl which are linked using direct endpoints. Each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from rest-dsl). By inlining (default) allows Camel to optimize and inline this as a single route, however this requires to use direct endpoints, which must be unique per service. If a route is not using direct endpoint then the [...] { "name": "camel.rest.jsonDataFormat", "description": "Sets a custom json data format to be used Important: This option is only for setting a custom name of the data format, not to refer to an existing data format instance.", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "string", "javaType": "java.lang.String" }, { "name": "camel.rest.port", "description": "Sets the port to use by the REST consumer", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "integer", "javaType": "int" }, { "name": "camel.rest.producerApiDoc", "description": "Sets the location of the api document (swagger api) the REST producer will use to validate the REST uri and query parameters are valid accordingly to the api document. This requires adding camel-openapi-java to the classpath, and any miss configuration will let Camel fail on startup and report the error(s). The location of the api document is loaded from classpath by default, but you can use file: or http: to refer to resources t [...] diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/restConfiguration.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/restConfiguration.json index 400dbb21f9e..2fff84c90f0 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/restConfiguration.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/restConfiguration.json @@ -31,7 +31,7 @@ "clientRequestValidation": { "index": 16, "kind": "attribute", "displayName": "Client Request Validation", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to enable validation of the client request to check: 1) Content-Type header matches what the Rest DSL consumes; returns HTTP Status 415 if validation error. 2) Accept header m [...] "enableCORS": { "index": 17, "kind": "attribute", "displayName": "Enable CORS", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to enable CORS headers in the HTTP response. The default value is false." }, "enableNoContentResponse": { "index": 18, "kind": "attribute", "displayName": "Enable No Content Response", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to return HTTP 204 with an empty body when a response contains an empty JSON object or XML root object. The default value is false." }, - "inlineRoutes": { "index": 19, "kind": "attribute", "displayName": "Inline Routes", "label": "consumer", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Inline routes in rest-dsl which are linked using direct endpoints. By default, each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route li [...] + "inlineRoutes": { "index": 19, "kind": "attribute", "displayName": "Inline Routes", "label": "consumer", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Inline routes in rest-dsl which are linked using direct endpoints. Each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from res [...] "jsonDataFormat": { "index": 20, "kind": "attribute", "displayName": "Json Data Format", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of specific json data format to use. By default jackson will be used. Important: This option is only for setting a custom name of the data format, not to refer to an existing data format instance." }, "xmlDataFormat": { "index": 21, "kind": "attribute", "displayName": "Xml Data Format", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of specific XML data format to use. By default jaxb will be used. Important: This option is only for setting a custom name of the data format, not to refer to an existing data format instance." }, "componentProperty": { "index": 22, "kind": "element", "displayName": "Component Property", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to configure as many additional properties for the rest component in use." }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd index f8884754fdf..f3ad55422af 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd @@ -16760,10 +16760,11 @@ default value is false. Default value: false <xs:annotation> <xs:documentation xml:lang="en"> <![CDATA[ -Inline routes in rest-dsl which are linked using direct endpoints. By default, each service in Rest DSL is an individual -route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from rest-dsl). -Enabling this allows Camel to optimize and inline this as a single route, however this requires to use direct endpoints, -which must be unique per service. This option is default false. Default value: false +Inline routes in rest-dsl which are linked using direct endpoints. Each service in Rest DSL is an individual route, +meaning that you would have at least two routes per service (rest-dsl, and the route linked from rest-dsl). By inlining +(default) allows Camel to optimize and inline this as a single route, however this requires to use direct endpoints, +which must be unique per service. If a route is not using direct endpoint then the rest-dsl is not inlined, and will +become an individual route. This option is default true. Default value: true ]]> </xs:documentation> </xs:annotation> diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/component/rest/RestRefTest.java b/components/camel-spring-xml/src/test/java/org/apache/camel/component/rest/RestRefTest.java index f900b1bb0f7..577622efe0b 100644 --- a/components/camel-spring-xml/src/test/java/org/apache/camel/component/rest/RestRefTest.java +++ b/components/camel-spring-xml/src/test/java/org/apache/camel/component/rest/RestRefTest.java @@ -30,7 +30,8 @@ public class RestRefTest extends SpringTestSupport { @Test public void testRestRefTest() throws Exception { - assertEquals(2 + 3, context.getRoutes().size()); + // inlined routes + assertEquals(3, context.getRoutes().size()); assertEquals(2, context.getRestDefinitions().size()); RestDefinition rest = context.getRestDefinitions().get(0); diff --git a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestManagementTest.java b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestManagementTest.java index 961eb441eaa..853e5dfce9d 100644 --- a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestManagementTest.java +++ b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestManagementTest.java @@ -44,7 +44,7 @@ public class RestManagementTest extends BaseUndertowTest { Set<ObjectName> s = mbeanServer.queryNames( new ObjectName("org.apache.camel:context=" + context.getManagementName() + ",type=endpoints,*"), null); - assertEquals(8, s.size(), "Could not find 8 endpoints: " + s); + assertEquals(6, s.size(), "Could not find 8 endpoints: " + s); // there should be 3 rest endpoints long count = s.stream().filter(p -> p.getCanonicalName().contains("rest")).count(); diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java b/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java index 4f929439f6c..5cc46647a6e 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java @@ -65,7 +65,7 @@ public class RestConfiguration { private RestBindingMode bindingMode = RestBindingMode.off; private boolean skipBindingOnErrorCode = true; private boolean clientRequestValidation; - private boolean inlineRoutes; + private boolean inlineRoutes = true; private boolean enableCORS; private boolean enableNoContentResponse; private String jsonDataFormat; @@ -442,11 +442,12 @@ public class RestConfiguration { /** * Inline routes in rest-dsl which are linked using direct endpoints. * - * By default, each service in Rest DSL is an individual route, meaning that you would have at least two routes per - * service (rest-dsl, and the route linked from rest-dsl). Enabling this allows Camel to optimize and inline this as - * a single route, however this requires to use direct endpoints, which must be unique per service. + * Each service in Rest DSL is an individual route, meaning that you would have at least two routes per service + * (rest-dsl, and the route linked from rest-dsl). By inlining (default) allows Camel to optimize and inline this as + * a single route, however this requires to use direct endpoints, which must be unique per service. If a route is + * not using direct endpoint then the rest-dsl is not inlined, and will become an individual route. * - * This option is default <tt>false</tt>. + * This option is default <tt>true</tt>. */ public void setInlineRoutes(boolean inlineRoutes) { this.inlineRoutes = inlineRoutes; diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java index 8f6bb7eed26..22ba27a215c 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java @@ -2560,8 +2560,7 @@ public abstract class AbstractCamelContext extends BaseService } else if (order.getRoute().isCreatedByRestDsl()) { rests++; } - boolean skip = order.getRoute().isCreatedByRestDsl() - || (!registerKamelets && order.getRoute().isCreatedByKamelet()) + boolean skip = (!registerKamelets && order.getRoute().isCreatedByKamelet()) || (!registerTemplates && order.getRoute().isCreatedByRouteTemplate()); if (!skip && ServiceStatus.Started.name().equals(status)) { started++; @@ -2599,7 +2598,7 @@ public abstract class AbstractCamelContext extends BaseService } else if (route.isCreatedByRestDsl()) { rests++; } - boolean skip = route.isCreatedByRestDsl() || (!registerKamelets && route.isCreatedByKamelet()) + boolean skip = (!registerKamelets && route.isCreatedByKamelet()) || (!registerTemplates && route.isCreatedByRouteTemplate()); // use basic endpoint uri to not log verbose details or potential sensitive data String uri = route.getEndpoint().getEndpointBaseUri(); @@ -2626,7 +2625,6 @@ public abstract class AbstractCamelContext extends BaseService if (!registerTemplates) { newTotal -= templates; } - newTotal -= rests; StringJoiner sj = new StringJoiner(" "); sj.add("total:" + newTotal); if (total != started) { @@ -3074,8 +3072,7 @@ public abstract class AbstractCamelContext extends BaseService } else if (order.getRoute().isCreatedByRestDsl()) { rests++; } - boolean skip = order.getRoute().isCreatedByRestDsl() - || (!registerKamelets && order.getRoute().isCreatedByKamelet()) + boolean skip = (!registerKamelets && order.getRoute().isCreatedByKamelet()) || (!registerTemplates && order.getRoute().isCreatedByRouteTemplate()); if (!skip && ServiceStatus.Stopped.name().equals(status)) { stopped++; @@ -3098,7 +3095,6 @@ public abstract class AbstractCamelContext extends BaseService if (!registerTemplates) { newTotal -= templates; } - newTotal -= rests; StringJoiner sj = new StringJoiner(" "); sj.add("total:" + newTotal); if (total != stopped) { diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/SourceDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/SourceDevConsole.java index c848030b181..ba7faf6e3d5 100644 --- a/core/camel-console/src/main/java/org/apache/camel/impl/console/SourceDevConsole.java +++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/SourceDevConsole.java @@ -89,7 +89,9 @@ public class SourceDevConsole extends AbstractDevConsole { sb.append(String.format("\n Source: %s", mrb.getSourceLocation())); } if (!code.isEmpty()) { + sb.append("\n"); sb.append(code); + sb.append("\n\n"); } } sb.append("\n"); diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java index 1a3a0d55e65..f0a2fc60f02 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java @@ -225,9 +225,38 @@ public class DefaultModel implements Model { RouteDefinition toBeInlined = directs.get(toUri); if (toBeInlined != null) { toBeRemoved.add(toBeInlined); + // inline the source loc:line as starting from this direct input + FromDefinition inlinedFrom = toBeInlined.getInput(); + from.setLocation(inlinedFrom.getLocation()); + from.setLineNumber(inlinedFrom.getLineNumber()); // inline by replacing the outputs r.getOutputs().clear(); r.getOutputs().addAll(toBeInlined.getOutputs()); + // and copy over various configurations + if (toBeInlined.getRouteId() != null) { + r.setId(toBeInlined.getRouteId()); + } + r.setNodePrefixId(toBeInlined.getNodePrefixId()); + r.setGroup(toBeInlined.getGroup()); + r.setAutoStartup(toBeInlined.getAutoStartup()); + r.setDelayer(toBeInlined.getDelayer()); + r.setInputType(toBeInlined.getInputType()); + r.setOutputType(toBeInlined.getOutputType()); + r.setLogMask(toBeInlined.getLogMask()); + r.setMessageHistory(toBeInlined.getMessageHistory()); + r.setStreamCache(toBeInlined.getStreamCache()); + r.setTrace(toBeInlined.getTrace()); + r.setStartupOrder(toBeInlined.getStartupOrder()); + r.setRoutePolicyRef(toBeInlined.getRoutePolicyRef()); + r.setRouteConfigurationId(toBeInlined.getRouteConfigurationId()); + r.setRoutePolicies(toBeInlined.getRoutePolicies()); + r.setShutdownRoute(toBeInlined.getShutdownRoute()); + r.setShutdownRunningTask(toBeInlined.getShutdownRunningTask()); + r.setErrorHandlerRef(toBeInlined.getErrorHandlerRef()); + r.setPrecondition(toBeInlined.getPrecondition()); + if (toBeInlined.isErrorHandlerFactorySet()) { + r.setErrorHandlerFactory(toBeInlined.getErrorHandlerFactory()); + } } } } diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/restConfiguration.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/restConfiguration.json index 400dbb21f9e..2fff84c90f0 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/restConfiguration.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/restConfiguration.json @@ -31,7 +31,7 @@ "clientRequestValidation": { "index": 16, "kind": "attribute", "displayName": "Client Request Validation", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to enable validation of the client request to check: 1) Content-Type header matches what the Rest DSL consumes; returns HTTP Status 415 if validation error. 2) Accept header m [...] "enableCORS": { "index": 17, "kind": "attribute", "displayName": "Enable CORS", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to enable CORS headers in the HTTP response. The default value is false." }, "enableNoContentResponse": { "index": 18, "kind": "attribute", "displayName": "Enable No Content Response", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to return HTTP 204 with an empty body when a response contains an empty JSON object or XML root object. The default value is false." }, - "inlineRoutes": { "index": 19, "kind": "attribute", "displayName": "Inline Routes", "label": "consumer", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Inline routes in rest-dsl which are linked using direct endpoints. By default, each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route li [...] + "inlineRoutes": { "index": 19, "kind": "attribute", "displayName": "Inline Routes", "label": "consumer", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Inline routes in rest-dsl which are linked using direct endpoints. Each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from res [...] "jsonDataFormat": { "index": 20, "kind": "attribute", "displayName": "Json Data Format", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of specific json data format to use. By default jackson will be used. Important: This option is only for setting a custom name of the data format, not to refer to an existing data format instance." }, "xmlDataFormat": { "index": 21, "kind": "attribute", "displayName": "Xml Data Format", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of specific XML data format to use. By default jaxb will be used. Important: This option is only for setting a custom name of the data format, not to refer to an existing data format instance." }, "componentProperty": { "index": 22, "kind": "element", "displayName": "Component Property", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to configure as many additional properties for the rest component in use." }, diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java index aa78b73fdc4..fea85633ba5 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java @@ -1153,7 +1153,7 @@ public class RouteDefinition extends OutputDefinition<RouteDefinition> /** * Is a custom error handler been set */ - boolean isErrorHandlerFactorySet() { + public boolean isErrorHandlerFactorySet() { return errorHandlerFactory != null; } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java index 71be26d83c8..7e3d15efe92 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java @@ -95,7 +95,7 @@ public class RestConfigurationDefinition { @Metadata(label = "consumer,advanced", javaType = "java.lang.Boolean", defaultValue = "false") private String enableNoContentResponse; @XmlAttribute - @Metadata(label = "consumer", javaType = "java.lang.Boolean", defaultValue = "false") + @Metadata(label = "consumer", javaType = "java.lang.Boolean", defaultValue = "true") private String inlineRoutes; @XmlAttribute @Metadata(label = "advanced") @@ -374,11 +374,12 @@ public class RestConfigurationDefinition { /** * Inline routes in rest-dsl which are linked using direct endpoints. * - * By default, each service in Rest DSL is an individual route, meaning that you would have at least two routes per - * service (rest-dsl, and the route linked from rest-dsl). Enabling this allows Camel to optimize and inline this as - * a single route, however this requires to use direct endpoints, which must be unique per service. + * Each service in Rest DSL is an individual route, meaning that you would have at least two routes per service + * (rest-dsl, and the route linked from rest-dsl). By inlining (default) allows Camel to optimize and inline this as + * a single route, however this requires to use direct endpoints, which must be unique per service. If a route is + * not using direct endpoint then the rest-dsl is not inlined, and will become an individual route. * - * This option is default <tt>false</tt>. + * This option is default <tt>true</tt>. */ public void setInlineRoutes(String inlineRoutes) { this.inlineRoutes = inlineRoutes; @@ -736,11 +737,12 @@ public class RestConfigurationDefinition { /** * Inline routes in rest-dsl which are linked using direct endpoints. * - * By default, each service in Rest DSL is an individual route, meaning that you would have at least two routes per - * service (rest-dsl, and the route linked from rest-dsl). Enabling this allows Camel to optimize and inline this as - * a single route, however this requires to use direct endpoints, which must be unique per service. + * Each service in Rest DSL is an individual route, meaning that you would have at least two routes per service + * (rest-dsl, and the route linked from rest-dsl). By inlining (default) allows Camel to optimize and inline this as + * a single route, however this requires to use direct endpoints, which must be unique per service. If a route is + * not using direct endpoint then the rest-dsl is not inlined, and will become an individual route. * - * This option is default <tt>false</tt>. + * This option is default <tt>true</tt>. */ public RestConfigurationDefinition inlineRoutes(String inlineRoutes) { setInlineRoutes(inlineRoutes); @@ -750,11 +752,12 @@ public class RestConfigurationDefinition { /** * Inline routes in rest-dsl which are linked using direct endpoints. * - * By default, each service in Rest DSL is an individual route, meaning that you would have at least two routes per - * service (rest-dsl, and the route linked from rest-dsl). Enabling this allows Camel to optimize and inline this as - * a single route, however this requires to use direct endpoints, which must be unique per service. + * Each service in Rest DSL is an individual route, meaning that you would have at least two routes per service + * (rest-dsl, and the route linked from rest-dsl). By inlining (default) allows Camel to optimize and inline this as + * a single route, however this requires to use direct endpoints, which must be unique per service. If a route is + * not using direct endpoint then the rest-dsl is not inlined, and will become an individual route. * - * This option is default <tt>false</tt>. + * This option is default <tt>true</tt>. */ public RestConfigurationDefinition inlineRoutes(boolean inlineRoutes) { setInlineRoutes(inlineRoutes ? "true" : "false"); diff --git a/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestGetPolicyTest.java b/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestGetPolicyTest.java index 4a5ba9ac86a..376b9149f8b 100644 --- a/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestGetPolicyTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestGetPolicyTest.java @@ -38,7 +38,8 @@ public class FromRestGetPolicyTest extends ContextTestSupport { @Test public void testFromRestModel() throws Exception { - assertEquals(2, context.getRoutes().size()); + // routes are inlined + assertEquals(1, context.getRoutes().size()); assertEquals(1, context.getRestDefinitions().size()); diff --git a/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestGetTest.java b/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestGetTest.java index aef7b5e57fe..2856445e2ed 100644 --- a/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestGetTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestGetTest.java @@ -41,7 +41,8 @@ public class FromRestGetTest extends ContextTestSupport { } protected int getExpectedNumberOfRoutes() { - return 2 + 3; + // routes are inlined + return 3; } @Test diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json index f1e51f670bf..f2f63e72a4a 100644 --- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json +++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json @@ -228,7 +228,7 @@ { "name": "camel.rest.endpointProperties", "description": "Sets additional options on endpoint level", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "object", "javaType": "java.util.Map" }, { "name": "camel.rest.host", "description": "Sets the hostname to use by the REST consumer", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "string", "javaType": "java.lang.String" }, { "name": "camel.rest.hostNameResolver", "description": "Sets the resolver to use for resolving hostname", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "object", "javaType": "org.apache.camel.spi.RestHostNameResolver", "defaultValue": "RestHostNameResolver.allLocalIp", "enum": [ "allLocalIp", "localIp", "localHostName" ] }, - { "name": "camel.rest.inlineRoutes", "description": "Inline routes in rest-dsl which are linked using direct endpoints. By default, each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from rest-dsl). Enabling this allows Camel to optimize and inline this as a single route, however this requires to use direct endpoints, which must be unique per service. This option is default false.", "sourceType" [...] + { "name": "camel.rest.inlineRoutes", "description": "Inline routes in rest-dsl which are linked using direct endpoints. Each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from rest-dsl). By inlining (default) allows Camel to optimize and inline this as a single route, however this requires to use direct endpoints, which must be unique per service. If a route is not using direct endpoint then the [...] { "name": "camel.rest.jsonDataFormat", "description": "Sets a custom json data format to be used Important: This option is only for setting a custom name of the data format, not to refer to an existing data format instance.", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "string", "javaType": "java.lang.String" }, { "name": "camel.rest.port", "description": "Sets the port to use by the REST consumer", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "integer", "javaType": "int" }, { "name": "camel.rest.producerApiDoc", "description": "Sets the location of the api document (swagger api) the REST producer will use to validate the REST uri and query parameters are valid accordingly to the api document. This requires adding camel-openapi-java to the classpath, and any miss configuration will let Camel fail on startup and report the error(s). The location of the api document is loaded from classpath by default, but you can use file: or http: to refer to resources t [...] diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc index a12a25f0edb..f95c98836b2 100644 --- a/core/camel-main/src/main/docs/main.adoc +++ b/core/camel-main/src/main/docs/main.adoc @@ -284,7 +284,7 @@ The camel.rest supports 28 options, which are listed below. | *camel.rest.endpointProperties* | Sets additional options on endpoint level | | Map | *camel.rest.host* | Sets the hostname to use by the REST consumer | | String | *camel.rest.hostNameResolver* | Sets the resolver to use for resolving hostname | RestHostNameResolver.allLocalIp | RestHostNameResolver -| *camel.rest.inlineRoutes* | Inline routes in rest-dsl which are linked using direct endpoints. By default, each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from rest-dsl). Enabling this allows Camel to optimize and inline this as a single route, however this requires to use direct endpoints, which must be unique per service. This option is default false. | false | boolean +| *camel.rest.inlineRoutes* | Inline routes in rest-dsl which are linked using direct endpoints. Each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from rest-dsl). By inlining (default) allows Camel to optimize and inline this as a single route, however this requires to use direct endpoints, which must be unique per service. If a route is not using direct endpoint then the rest-dsl is not inlined, a [...] | *camel.rest.jsonDataFormat* | Sets a custom json data format to be used Important: This option is only for setting a custom name of the data format, not to refer to an existing data format instance. | | String | *camel.rest.port* | Sets the port to use by the REST consumer | | int | *camel.rest.producerApiDoc* | Sets the location of the api document (swagger api) the REST producer will use to validate the REST uri and query parameters are valid accordingly to the api document. This requires adding camel-openapi-java to the classpath, and any miss configuration will let Camel fail on startup and report the error(s). The location of the api document is loaded from classpath by default, but you can use file: or http: to refer to resources to load from file or http ur [...] diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedFromRestGetTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedFromRestGetTest.java index c4e1df5bd7c..cca8e7ed776 100644 --- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedFromRestGetTest.java +++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedFromRestGetTest.java @@ -31,6 +31,7 @@ import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.condition.OS; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -78,12 +79,13 @@ public class ManagedFromRestGetTest extends ManagementTestSupport { // and we should have rest in the routes that indicate its from a rest dsl assertTrue(xml2.contains("rest=\"true\"")); - assertTrue(xml2.matches("[\\S\\s]* <to id=\"to[0-9]+\" uri=\"direct:hello\"/>[\\S\\s]*")); - assertTrue(xml2.matches("[\\S\\s]*<to id=\"to[0-9]+\" uri=\"direct:bye\"/>[\\S\\s]*")); + // routes are inlined + assertFalse(xml2.matches("[\\S\\s]* <to id=\"to[0-9]+\" uri=\"direct:hello\"/>[\\S\\s]*")); + assertFalse(xml2.matches("[\\S\\s]*<to id=\"to[0-9]+\" uri=\"direct:bye\"/>[\\S\\s]*")); assertTrue(xml2.matches("[\\S\\s]*<to id=\"to[0-9]+\" uri=\"mock:update\"/>[\\S\\s]*")); - // there should be 3 + 2 routes - assertEquals(3 + 2, context.getRouteDefinitions().size()); + // there should be 3 routes + assertEquals(3, context.getRouteDefinitions().size()); } @Override diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedFromRestPlaceholderTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedFromRestPlaceholderTest.java index c09629efc86..f9648e9b2cc 100644 --- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedFromRestPlaceholderTest.java +++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedFromRestPlaceholderTest.java @@ -79,8 +79,8 @@ public class ManagedFromRestPlaceholderTest extends ManagementTestSupport { // and we should have rest in the routes that indicate its from a rest dsl assertTrue(xml2.contains("rest=\"true\"")); - // there should be 3 + 2 routes - assertEquals(3 + 2, context.getRouteDefinitions().size()); + // there should be 3 routes (inlined) + assertEquals(3, context.getRouteDefinitions().size()); } @Override diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_5.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_5.adoc index d156d84e35b..3c4353b4af7 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_5.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_5.adoc @@ -35,6 +35,15 @@ The following deprecated methods from the `AbstractCamelContext`, deprecated on Users of these methods should use the respective operations from the `ExtendedCamelContext` (accessed via `getCamelContextExtension()`), instead. +=== Rest DSL + +Camel has changed the default value for `inlineRoutes=false` to `inlineRoutes=false` in `restConfiguration`. +It is very typical to define Rest DSL and for each service api, then call a Camel route via `direct` endpoints. +By inlining these two, then you only have 1 route in Camel instead of 2. This helps reduce the clutter of routes +that otherwise is in use when using Rest DSL and many services. + +You can restore to old behaviour by setting the option back to `inlineRoutes=false`. + === Intercept EIP The `interceptFrom` and `interceptSentToEndpoint` EIPs is now storing the intercepted endpoint using key `Exchange.INTERCEPTED_ENDPOINT` diff --git a/dsl/camel-js-dsl/src/test/java/org/apache/camel/dsl/js/JavaScriptRoutesBuilderLoaderTest.java b/dsl/camel-js-dsl/src/test/java/org/apache/camel/dsl/js/JavaScriptRoutesBuilderLoaderTest.java index b742ed8036a..3451e103669 100644 --- a/dsl/camel-js-dsl/src/test/java/org/apache/camel/dsl/js/JavaScriptRoutesBuilderLoaderTest.java +++ b/dsl/camel-js-dsl/src/test/java/org/apache/camel/dsl/js/JavaScriptRoutesBuilderLoaderTest.java @@ -112,7 +112,8 @@ public class JavaScriptRoutesBuilderLoaderTest { PluginHelper.getRoutesLoader(context).loadRoutes(resource); assertThat(context.getRestDefinitions()).hasSize(1); - assertThat(context.getRouteDefinitions()).hasSize(2); + // routes are inlined + assertThat(context.getRouteDefinitions()).hasSize(1); assertThat(context.getRestDefinitions()).first().satisfies(d -> { assertThat(d.getProduces()).isEqualTo("text/plain"); diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerBase.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerBase.java index 9135519540e..a1f0dae738d 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerBase.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerBase.java @@ -18,6 +18,7 @@ package org.apache.camel.dsl.yaml.common; import java.util.Locale; +import org.apache.camel.CamelContextAware; import org.apache.camel.LineNumberAware; import org.apache.camel.dsl.yaml.common.exception.UnsupportedFieldException; import org.apache.camel.dsl.yaml.common.exception.UnsupportedNodeTypeException; @@ -134,19 +135,23 @@ public abstract class YamlDeserializerBase<T> extends YamlDeserializerSupport im } protected void onNewTarget(Node node, T target, int line) { + YamlDeserializationContext ctx = getDeserializationContext(node); + if (ctx != null && target instanceof CamelContextAware) { + CamelContextAware.trySetCamelContext(target, ctx.getCamelContext()); + } + // enrich model with source location:line number if (target instanceof LineNumberAware && line != -1) { LineNumberAware lna = (LineNumberAware) target; lna.setLineNumber(line); - YamlDeserializationContext ctx = getDeserializationContext(node); + ctx = getDeserializationContext(node); if (ctx != null) { lna.setLocation(ctx.getResource().getLocation()); } } if (target instanceof ResourceAware) { ResourceAware ra = (ResourceAware) target; - YamlDeserializationContext ctx = getDeserializationContext(node); if (ctx != null) { ra.setResource(ctx.getResource()); } diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java index 1b1bea8114e..68306931efa 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java @@ -13802,7 +13802,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { @YamlProperty(name = "endpointProperty", type = "array:org.apache.camel.model.rest.RestPropertyDefinition", description = "Allows to configure as many additional properties for the rest endpoint in use.", displayName = "Endpoint Property"), @YamlProperty(name = "host", type = "string", description = "The hostname to use for exposing the REST service.", displayName = "Host"), @YamlProperty(name = "hostNameResolver", type = "enum:allLocalIp,localHostName,localIp", defaultValue = "allLocalIp", description = "If no hostname has been explicit configured, then this resolver is used to compute the hostname the REST service will be using.", displayName = "Host Name Resolver"), - @YamlProperty(name = "inlineRoutes", type = "boolean", description = "Inline routes in rest-dsl which are linked using direct endpoints. By default, each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from rest-dsl). Enabling this allows Camel to optimize and inline this as a single route, however this requires to use direct endpoints, which must be unique per service. This option [...] + @YamlProperty(name = "inlineRoutes", type = "boolean", description = "Inline routes in rest-dsl which are linked using direct endpoints. Each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from rest-dsl). By inlining (default) allows Camel to optimize and inline this as a single route, however this requires to use direct endpoints, which must be unique per service. If a route is n [...] @YamlProperty(name = "jsonDataFormat", type = "string", description = "Name of specific json data format to use. By default jackson will be used. Important: This option is only for setting a custom name of the data format, not to refer to an existing data format instance.", displayName = "Json Data Format"), @YamlProperty(name = "port", type = "string", description = "The port number to use for exposing the REST service. Notice if you use servlet component then the port number configured here does not apply, as the port number in use is the actual port number the servlet component is using. eg if using Apache Tomcat its the tomcat http port, if using Apache Karaf its the HTTP service in Karaf that uses port 8181 by default etc. Though in those situations setting the port [...] @YamlProperty(name = "producerApiDoc", type = "string", description = "Sets the location of the api document the REST producer will use to validate the REST uri and query parameters are valid accordingly to the api document. The location of the api document is loaded from classpath by default, but you can use file: or http: to refer to resources to load from file or http url.", displayName = "Producer Api Doc"), diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json index 126d3f1404f..3533326fdc1 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json @@ -15301,7 +15301,7 @@ "inlineRoutes" : { "type" : "boolean", "title" : "Inline Routes", - "description" : "Inline routes in rest-dsl which are linked using direct endpoints. By default, each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from rest-dsl). Enabling this allows Camel to optimize and inline this as a single route, however this requires to use direct endpoints, which must be unique per service. This option is default false." + "description" : "Inline routes in rest-dsl which are linked using direct endpoints. Each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from rest-dsl). By inlining (default) allows Camel to optimize and inline this as a single route, however this requires to use direct endpoints, which must be unique per service. If a route is not using direct endpoint then the rest-dsl is not inlined, an [...] }, "jsonDataFormat" : { "type" : "string",